2010-07-16 39 views
9

试图获取出现在子女FrameworkElement中的OnMouse事件。父元素是Panel(并且Background属性不为空)。WPF FrameworkElement未接收鼠标输入

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> 

Docs说FrameworkElement处理输入,但为什么不在这种情况下?

回答

1

我能够重现您描述的情况。我做了一些玩耍,直到我将MyFrameworkElement的基类从FrameworkElement更改为更具体的东西,如UserControl,事件才开始像他们应该发射一样。我不是100%确定为什么会这样,但我会建议使用衍生自FrameworkElement的其中一个类别,以满足您的需求(如Panel,如您在上例中所做的或Button)。

我很好奇,想知道你上面的例子会产生这些结果的确切原因...

+0

感谢您的答复。我一直在玩弄一点点,并设法让我需要通过添加以下到FrameworkElement的行为: 保护覆盖无效的OnRender(的DrawingContext的DrawingContext) { 尺寸renderSize = this.RenderSize; Rect rect = new Rect(renderSize); Pen pen = new Pen(Brushes.Transparent,0.0); 012Context.DrawRectangle(Brushes.Transparent,pen,rect); } 也许FrameworkElement的大小为零,除非添加了一些东西? – lava 2010-07-16 23:11:10

20

OnMouseDown如果你的元素响应命中测试才会被调用。见Hit Testing in the Visual Layer。默认实现将对OnRender中绘制的图形进行命中测试。使用Transparent背景创建Panel可以工作,因为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); 
} 
+0

谢谢你的一个很好的解释! – 2011-01-11 02:05:38