我无法在自定义FrameworkElement上触发MouseMove事件,该事件将用作绘图的主机。
案例显示在下一个示例代码中:
namespace WpfAppTest
{
public class VisualPresenter : FrameworkElement
{
private readonly List<Visual> VisualChildren = new List<Visual>();
public Size ViewSize = new Size(500, 300);
public VisualPresenter()
{
var DrwVis = new DrawingVisual();
using (var Context = DrwVis.RenderOpen())
Context.DrawDrawing(
new GeometryDrawing(Brushes.LightSkyBlue, null,
new RectangleGeometry(new Rect(ViewSize))));
this.VisualChildren.Add(DrwVis);
}
protected override int VisualChildrenCount { get { return VisualChildren.Count; } }
protected override Visual GetVisualChild(int index)
{
if (index < 0 || index >= VisualChildren.Count) throw new ArgumentOutOfRangeException();
return VisualChildren[index];
}
protected override Size MeasureOverride(Size AvailableSize)
{ return this.ViewSize; }
protected override Size ArrangeOverride(Size FinalSize)
{ return base.ArrangeOverride(FinalSize); }
protected override void OnMouseMove(MouseEventArgs e)
{
// Why this is not fired when the mouse is over???
Application.Current.MainWindow.Title = "Moving at: " + e.GetPosition(null);
}
}
}
这个“自定义控件”(如果这个概念适用于此处)可以在插入主窗口xaml时轻松测试...
<Window x:Class="WpfAppTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfAppTest"
mc:Ignorable="d"
Title="MainWindow" Height="700" Width="600">
<Grid>
<local:VisualPresenter />
</Grid>
</Window>
那么,缺少什么?
更新1: 我发现捕获鼠标时会触发mousemove事件,例如在VisualPresenter构造函数中添加下一行时:
this.Loaded += (s, e) => CaptureMouse();
更新2: 或者,也可以触发mousemove事件,而不是使用List,而是使用VisualCollection来注册子项。但是我更喜欢使用List来存储不仅仅是视觉(即识别那些暴露的视觉效果的键)。
答案 0 :(得分:1)
没有背景被认为是空洞的,不能吸收鼠标事件。框架元素默认情况下没有可视化。因此,将根据OnRender方法中绘制的内容完成命中测试。可以通过在渲染上绘制一个空的透明矩形来启用命中测试。
protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawRectangle(Brushes.Transparent, new Pen(Brushes.Transparent, 1), new Rect(0, 0, this.ActualWidth, this.ActualHeight));
base.OnRender(drawingContext);
}
答案 1 :(得分:1)
在分析(源代码深入研究)VisualCollection类如何工作之后,我发现缺少的部分是将新的可视对象附加到底层的WPF可视化树。那么,现在我们有......
this.VisualChildren.Add(DrwVis); // This only shows the visual
this.AddVisualChild(DrwVis); // This links the visual to its parent
瞧,瞧!点击测试Works和mousemove事件被触发。