Попытка получить события OnMouse, появляющиеся в ребенке FrameworkElement
. Родительский элемент является a Panel
(и Background
свойство не является Пустым).
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
Вход дескрипторов, но почему не в этом сценарии?
Я смог воспроизвести описанный вами сценарий. Я немного поигрался, и только когда я изменил базовый класс MyFrameworkElement
с FrameworkElement
на что-то более конкретное, например, UserControl
, события начали происходить как положено. Я не уверен на 100%, почему так происходит, но я бы рекомендовал использовать один из классов, производных от FrameworkElement
, который подходит для ваших нужд (например, Panel
, как вы сделали в примере выше, или Button
).
Мне было бы интересно узнать точную причину, по которой ваш пример выше дает такие результаты...
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);
}