WPF FrameworkElement, не получающий Мышь, вводится

Попытка получить события OnMouse, появляющиеся в ребенке FrameworkElement. Родительский элемент является a PanelBackground свойство не является Пустым).

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 никогда не называют, событие всегда не обработано, и Ищейка говорит мне, что направленное событие только когда-либо, кажется, добирается до 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 Вход дескрипторов, но почему не в этом сценарии?

10
задан Dave Clemmer 26 September 2013 в 19:20
поделиться

2 ответа

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

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

1
ответ дан 3 December 2019 в 16:51
поделиться

OnMouseDown будет вызван только если ваш элемент отвечает на Hit Testing. См. раздел Тестирование на попадание в визуальном слое. Реализация по умолчанию будет выполнять проверку на попадание в графику, нарисованную в 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);
}
23
ответ дан 3 December 2019 в 16:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: