命中测试:是指某点是否在目标元素范围之内
//返回点击目标 即命中测试结果对象
HitTestResult hitTestResult=VisualTreeHelper.HitTest(this,point);
hitTestResult.VisualHit as DrawingVisual; //命中目标封装在命中测试的VisualHit 中,这个
属性的类型时DependencyObject 即依赖对象,因此这里需要转换成 DrawingVisual类型
示例代码
using System.Windows;
using System.Windows.Media;
namespace WpfApp_DrawingVisual
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
MouseLeftButtonDown += MainWindow_MouseLeftButtonDown;
MouseRightButtonDown += MainWindow_MouseRightButtonDown;
}
private void MainWindow_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Point point = e.GetPosition(myPanel); //获取鼠标点击位置
Visual visual = GetVisual(point); //根据点击位置获取命中对象
if (visual != null)
{
myPanel.DeleteVisual(visual); //删除命中对象
}
}
private void MainWindow_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Point pointClicked=e.GetPosition(myPanel);
DrawingVisual visual = new DrawingVisual();
DrawSqure(visual, pointClicked);
myPanel.AddVisual(visual);
}
public DrawingVisual GetVisual(Point point) {
HitTestResult hitTestResult = VisualTreeHelper.HitTest(this, point);
if (hitTestResult != null)
{
return hitTestResult.VisualHit as DrawingVisual;
}
else
return null;
}
private void DrawSqure(DrawingVisual visual, Point topLeftCorner)
{
DrawingContext dc = visual.RenderOpen();
Brush brush = Brushes.LightGreen;
Pen pen = new Pen(Brushes.SteelBlue, 3);
dc.DrawRectangle(brush, pen,new Rect(topLeftCorner, new Size(50, 50)));
dc.Close();
}
}
}
自定义容器类
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media;
namespace WpfApp_DrawingVisual
{
public class MyPanel:Panel
{
private List<Visual> visuals = new List<Visual>(); //定义可视化集合对象
protected override Visual GetVisualChild(int index) //重写可视化对象获取方法
{
return visuals[index];
}
protected override int VisualChildrenCount => visuals.Count; //重写可视化属性,可视化元素数量
public void AddVisual(Visual visual) { //添加可视化元素方法
visuals.Add(visual);
base.AddLogicalChild(visual); // 把可视化对象添加到逻辑树上
base.AddVisualChild(visual); //把可视化对象添加的可视树上
}
public void DeleteVisual(Visual visual) //删除可视化元素
{
visuals.Remove(visual);
base.RemoveVisualChild(visual);
base.RemoveLogicalChild(visual);
}
}
}