12

试图让 OnMouse 事件出现在 child 中FrameworkElement。父元素是 a 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处理输入,但为什么不在这种情况下呢?

4

2 回答 2

23

OnMouseDown只有当您的元素响应命中测试时才会调用。请参阅视觉层中的命中测试。默认实现将对OnRender. 创建Panel具有Transparent背景的 a 是可行的,因为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);
}
于 2010-07-17T15:36:34.393 回答
1

我能够重现您描述的场景。我做了一些尝试,直到我将MyFrameworkElementfrom的基类更改为FrameworkElement更具体的东西,就像UserControl事件开始按应有的方式触发一样。我不是 100% 确定为什么会这样,但我建议使用从中派生的类之一FrameworkElement来满足您的需求(例如Panel,就像您在上面的示例中所做的那样,或者Button)。

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

于 2010-07-16T22:47:21.377 回答