2010-07-16 4 views
9

Попытка получить события OnMouse, появляющиеся у ребенка FrameworkElement. Родительский элемент - это 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: protected override void OnRender (DrawingContext drawingContext) { Размер renderSize = this.RenderSize; Rect rect = new Rect (renderSize); Pen pen = new Pen (Brushes.Transparent, 0.0); drawingContext.DrawRectangle (Brushes.Transparent, pen, rect); } Возможно, элемент FrameworkElement равен нулю, если только что-то не добавлено к нему? – lava

20

OnMouseDown будет вызываться только если ваш элемент реагирует на Hit тестирование. См. Hit Testing in the Visual Layer. Реализация по умолчанию приведет к тестированию против графики, нарисованной в 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); 
} 
+0

Спасибо за отличное объяснение! –

Смежные вопросы