2010-07-16 2 views
9

Tentative d'affichage des événements OnMouse dans un enfant FrameworkElement. L'élément parent est un Panel (et la propriété Background n'est pas Null).WPF FrameworkElement ne recevant pas l'entrée de la souris

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 ne sera jamais appelé, événement est toujours et Snoop unhandled me dit que l'événement routé ne semble jamais aller aussi loin que l'élément 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 disent que FrameworkElement poignées d'entrée, mais pourquoi pas dans ce scénario?

Répondre

1

J'ai été capable de reproduire le scénario que vous avez décrit. J'ai joué un peu, et ce n'est que lorsque j'ai changé la classe MyFrameworkElement de FrameworkElement pour quelque chose de plus concret, comme UserControl que les événements ont commencé à se déclencher comme ils le devraient. Je ne suis pas sûr à 100% pourquoi ce serait, mais je recommanderais d'utiliser l'une des classes dérivées de FrameworkElement qui conviendrait à vos besoins (comme Panel, comme vous l'avez fait dans l'exemple ci-dessus, ou Button).

Je serais curieux de connaître la raison exacte de votre exemple ci-dessus produit ces résultats ...

+0

Merci pour votre réponse. J'ai joué autour pendant un petit peu et a réussi à obtenir le comportement dont j'ai besoin en ajoutant ce qui suit à FrameWorkElement: protected override void OnRender (DrawingContext drawingContext) { Taille renderSize = this.RenderSize; Rect rect = new Rect (renderSize); Stylo à bille = nouveau stylo (pinceaux.Transparent, 0.0); drawingContext.DrawRectangle (pinceaux.Transparent, stylo, rect); } Peut-être que FrameworkElement a une taille nulle à moins que quelque chose n'y soit ajouté? – lava

20

OnMouseDown ne sera appelée si votre élément répond à Hit Test. Voir Hit Testing in the Visual Layer. L'implémentation par défaut effectuera le test de hit par rapport aux graphiques dessinés dans OnRender. La création d'un Panel avec un arrière-plan Transparent fonctionne car Panel dessine un rectangle sur toute sa surface et ce rectangle captera le test d'atteinte. Vous pouvez obtenir le même effet en remplaçant OnRender pour dessiner un rectangle transparent:

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

Vous pouvez également remplacer HitTestCore de sorte que tous les clics sont comptés comme coups:

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

Merci pour une excellente explication! –

Questions connexes