2010-05-31 7 views
5

J'essaye de faire une belle "glisser-déposer" dans WPF qui est affichée dans la couche adorner quand quelque chose est glissé dans l'application principale. Le problème est que je ne reçois aucun événement de mon adorateur, même si, selon la documentation, il devrait recevoir tous les événements d'entrée, car il est dans un ordre z plus élevé.Aucun événement passé à WPF couche adorner

Pour déboguer mon problème, j'ai créé un exemple très simple où j'ai un contrôle utilisateur avec seulement un bouton dedans. Ce contrôle utilisateur est affiché dans la couche Adorner, mais je ne peux pas cliquer sur le bouton. Pourquoi? Qu'est ce que j'ai mal fait?

Ma classe Adorner est construit comme ceci:

public ShellOverlayAdorner(UIElement element, AdornerLayer adornerLayer) 
     :base(element) 
    { 
     _adornerLayer = adornerLayer; 

     _overlayView = new AdornedElement(); 
     _overlayView.AllowDrop = true; 
     _adornerLayer.Add(this); 
    } 

et est créé dans la fenêtre principale par

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     adornerLayer = AdornerLayer.GetAdornerLayer(MyTopGridWithButtonInIt); 
     ShellOverlayAdorner shell = new ShellOverlayAdorner(MyTopGridWithButtonInIt, adornerLayer); 

    } 

Je ne reçois aucun événement du tout de mon contrôle, à savoir pas de clics de souris , souris sur, clics de bouton. Je ne peux même pas cliquer sur le bouton dans la couche adorner. Qu'est ce que j'ai mal fait?

+1

Cela fonctionne bien pour moi ... Etes-vous sûr n'avez pas défini IsHitTestVisible false sur votre Adorner? –

+0

Hmmm .. Etrange, parce que je reçois ceci pour tous les projets de test que je crée. Non, je n'ai pas défini IsHitTestVisible sur false. J'ai testé le réglage à la fois vrai et faux pour obtenir un changement, mais rien ne se passe. – Johanna

Répondre

11

Je ne sais pas si vous avez déjà essayé cela: Si vous voulez que l'élément ajouté réagisse aux événements, je pense que l'élément doit être lié à l'arbre visuel de l'adorner. La façon de le faire est d'utiliser un VisualCollection, intitialized au Adorner lui-même, ou du moins, de cette façon, il semble fonctionner:

VisualCollection visualChildren; 
    FrameworkElement @object; 

    public CustomAdorner(UIElement adornedElement) : 
     base(adornedElement) 
    { 
     visualChildren = new VisualCollection(this); 
     @object = new Button {Content = "prova"}; 
     visualChildren.Add(@object); 
    } 
    protected override Visual GetVisualChild(int index) 
    { 
     return visualChildren[index]; 
    } 

De cette façon, les événements sont correctement acheminés.

1

Je viens d'avoir le même problème. Suite à l'avis de MSDN triés pour moi:

Les ornements reçoivent des événements d'entrée juste comme tout autre FrameworkElement. Parce qu'un Adorner a toujours un z-ordre supérieur à l'élément qu'il agrémente, l'Adorner reçoit des événements d'entrée (raccrochage ou MouseMove) qui peuvent être destinés à l'élément orné sous-jacent. Un adorateur peut écouter certains événements d'entrée et les transmettre à à l'élément orné sous-jacent par en sur-relançant l'événement.

Pour activer pass-through a frappé les tests de éléments sous Adorner, définissez le coup test de propriété IsHitTestVisible à faux sur le Adorner.

i.e. Dans le Adorner lui-même, assurez-vous IsHitTestVisible = false