WPF FrameworkElement не получает ввод мыши - PullRequest
9 голосов
/ 17 июля 2010

Попытка получить события 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 обрабатывает ввод, но почему бы не в этом сценарии?

Ответы [ 2 ]

21 голосов
/ 17 июля 2010

OnMouseDown будет вызываться, только если ваш элемент реагирует на проверку удара. См. Тестирование попаданий в визуальном слое . Реализация по умолчанию выполнит тестирование попадания по графике, нарисованной в 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 голос
/ 17 июля 2010

Мне удалось воспроизвести сценарий, который вы описали.Я немного поигрался, и только когда я изменил базовый класс MyFrameworkElement с FrameworkElement на что-то более конкретное, например UserControl, события начали срабатывать так, как они должны были.Я не уверен на 100%, почему это так, но я бы порекомендовал использовать один из классов, полученных из FrameworkElement, который бы соответствовал вашим потребностям (например, Panel, как вы делали в примере выше, или Button),

Мне было бы интересно узнать точную причину, по которой ваш пример дает такие результаты ...

...