想要达到的效果:
在一个canvas里面,画一个图形(可能是规则的矩形、也可能是不规则的曲线),
要求点击到图形边缘的时候就可以选中图形,不需要非得点击到图形内部。
代码如下,是个C#控制台程序:
环境:vs2008、没打sp1补丁。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;
using System.Runtime.InteropServices;
using System.Security;
using System.Resources;
using System.Windows.Media.Effects;
using System.Windows.Input;
namespace H
{
class Program
{
[STAThread]
public static void Main(string[] args)
{
Window w = new Window();
Canvas can = new Canvas();
can.Width = 600;
can.Height = 500;
can.Children.Add(new MyV());
w.Content = can;
w.ShowDialog();
}
}
/// <summary>
/// 想达到的效果是:点击图形的周围(不在图形内部)也可以选中图形,在OnRender里面分别把曲线和矩形的画法解开,就能看出差别了
/// </summary>
public class MyV : FrameworkElement
{
TranslateTransform _trans = new TranslateTransform();
public MyV()
{
this.RenderTransform = _trans;
this.Margin = new Thickness(50);
}
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
Point p = hitTestParameters.HitPoint;
EllipseGeometry ell = new EllipseGeometry(p, 10, 10);
_he = null;
VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(Hit), new GeometryHitTestParameters(ell));
if (_he != null && _he.VisualHit is MyV) return new PointHitTestResult(this, hitTestParameters.HitPoint);
return null;
}
HitTestResult _he = null;
private HitTestResultBehavior Hit(HitTestResult he)
{
_he = he;
return HitTestResultBehavior.Continue;
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
OuterGlowBitmapEffect myGlowEffect = new OuterGlowBitmapEffect();
myGlowEffect.GlowColor = Colors.Purple;
myGlowEffect.GlowSize = 10;
myGlowEffect.Noise = 1;
myGlowEffect.Opacity = 0.4;
this.BitmapEffect = myGlowEffect;
}
protected override void OnMouseLeave(MouseEventArgs e)
{
this.BitmapEffect = null;
}
//用一条曲线可以,但是一个矩形就不行
protected override void OnRender(DrawingContext drawingContext)
{
//Pen pen = new Pen(Brushes.Red, 1);
//drawingContext.DrawLine(pen, new Point(0, 0), new Point(10, 10));
//drawingContext.DrawLine(pen, new Point(20, 0), new Point(10, 10));
//drawingContext.DrawLine(pen, new Point(20, 0), new Point(30, 100));
//drawingContext.DrawLine(pen, new Point(400, 300), new Point(30, 100));
drawingContext.DrawRectangle(Brushes.Red, new Pen(Brushes.Green, 2), new Rect(0, 0, 100, 100));
}
}
}