尝试让OnMouse事件出现在孩子FrameworkElement
中。父元素是Panel
(并且Background
属性不是Null)。
class MyFrameworkElement : FrameworkElement
{
protected override void OnMouseDown(MouseButtonEventArgs e)
{
// Trying to get here!
base.OnMouseDown(e);
}
}
public class MyPanel : Panel
{
protected override void OnMouseDown(MouseButtonEventArgs e)
{
// This is OK
base.OnMouseDown(e);
}
}
OnMouse永远不会被调用,事件总是未被处理,Snoop告诉我路由事件似乎只能到Panel
元素。
<Window
x:Class="WpfApplication5.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:WpfApplication5"
Title="Window1" Height="300" Width="300">
<Border x:Name="myBorder" Background="Red">
<l:MyPanel x:Name="myPanel" Background="Transparent">
<l:MyFrameworkElement x:Name="myFE"/>
</l:MyPanel>
</Border>
</Window>
文档说FrameworkElement
处理输入,但为什么不处理这种情况?
答案 0 :(得分:21)
OnMouseDown
。见Hit Testing in the Visual Layer。默认实现将针对OnRender
中绘制的图形进行命中测试。创建具有Panel
背景的Transparent
是有效的,因为Panel
在其整个区域上绘制了一个矩形,并且该矩形将捕获命中测试。您可以通过覆盖OnRender
来绘制透明矩形来获得相同的效果:
protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawRectangle(Brushes.Transparent, null,
new Rect(0, 0, RenderSize.Width, RenderSize.Height));
}
您还可以覆盖HitTestCore
,以便将所有点击计为点击次数:
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
return new PointHitTestResult(this, hitTestParameters.HitPoint);
}
答案 1 :(得分:1)
我能够重现你描述的场景。我做了一些游戏,直到我将MyFrameworkElement
的基类从FrameworkElement
更改为更具体的内容,例如UserControl
,事件开始像他们应该开始一样。我不是100%确定为什么会这样,但我建议使用一个适合您需求的FrameworkElement
派生类(如Panel
,如上例所示,或者Button
)。
我很想知道上面的例子产生这些结果的确切原因......