2010-07-16 16 views
9

Intentando que los eventos de OnMouse aparezcan en un niño FrameworkElement. El elemento primario es Panel (y la propiedad Background no es nula).WPF FrameworkElement no recibe entrada de mouse

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 nunca se llama, el evento es siempre controlada y Snoop me dice que el evento enrutado solamente nunca parece llegar tan lejos como el elemento 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 decir que FrameworkElement maneja la entrada, pero por qué no en este escenario?

Respuesta

1

Pude reproducir el escenario que describió. Jugué un poco, y no fue hasta que cambié la clase base de MyFrameworkElement de FrameworkElement a algo más concreto, como UserControl, que los eventos comenzaron a dispararse como debían. No estoy 100% seguro de por qué sería esto, pero recomendaría utilizar una de las clases derivadas de FrameworkElement que se ajusten a sus necesidades (como Panel, como lo hizo en el ejemplo anterior, o Button).

Sería curioso saber la razón exacta de su ejemplo anterior produce estos resultados ...

+0

Gracias por su respuesta. He estado jugando un poco y logré obtener el comportamiento que necesito agregando lo siguiente a FrameWorkElement: protected override void OnRender (DrawingContext drawingContext) { Tamaño renderSize = this.RenderSize; Rect rect = new Rect (renderSize); Bolígrafo = bolígrafo nuevo (Cepillos.Transparente, 0.0); drawingContext.DrawRectangle (Brushes.Transparent, pen, rect); } ¿Quizás FrameworkElement tiene un tamaño cero a menos que se le agregue algo? – lava

20

OnMouseDown es llamado solo si su elemento responde a Hit Pruebas. Ver Hit Testing in the Visual Layer. La implementación predeterminada hará pruebas de impacto contra los gráficos dibujados en OnRender. Crear un Panel con un fondo Transparent funciona porque Panel dibuja un rectángulo en toda su área, y ese rectángulo capturará la prueba de impacto. Se puede obtener el mismo efecto anulando OnRender para dibujar un rectángulo transparente:

protected override void OnRender(DrawingContext drawingContext) 
{ 
    drawingContext.DrawRectangle(Brushes.Transparent, null, 
     new Rect(0, 0, RenderSize.Width, RenderSize.Height)); 
} 

También podría invalidar HitTestCore de manera que todos los clics se cuentan como éxitos:

protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) 
{ 
    return new PointHitTestResult(this, hitTestParameters.HitPoint); 
} 
+0

¡Gracias por una excelente explicación! –

Cuestiones relacionadas