2017-09-11 6 views
-1

J'ai une grille/panneau sur mon interface utilisateur qui peut prendre une action de baisse. Le contrôle est une grille avec du contenu créé dynamiquement (une boîte de vue contenant un panneau de bordures de pile si cela est important). Lorsque je fais glisser des informations pertinentes dans la grille, je veux qu'elles changent (régénèrent) le contenu interne et quand il tombe ou quitte il devrait revenir à la normale. J'ai les méthodes 'change it' et 'put it back' qui fonctionnent très bien, mais j'ai du mal à déterminer quand les appeler. J'ai glisser glisser et laisser des événements de quitter sur la grille. L'entrée fonctionne très bien, mais le congé ne l'est pas. Dès que la souris survole le haut du contenu à l'intérieur de la grille, elle déclenche un événement glisser-déposer, donc il change le contenu (et si cela le remet hors du contenu enfant, il tire le glisser-déposer et clignote) . Ma première pensée a été de simplement déterminer si la souris est toujours sur la grille et juste de se débarrasser sans remettre le contenu. Cependant, cela ne semble pas fonctionner. Voici mon code d'autorisation de glisser:IsMouseOver et DragLeave ne fonctionnent pas correctement

 private void Grid_DragLeave(object sender, DragEventArgs e) 
    { 
     var wizard = DataContext as WizardVM; 
     var gd = sender as Grid; 

     if (wizard == null || gd == null || gd.IsMouseOver || 
      gd.Children.Cast<FrameworkElement>().Any(x => x.IsMouseOver)) return; 

     wizard.Assembly.CollapsePreview(); 
    } 

Comme vous pouvez le voir, j'ai même essayé de itérer les enfants de la grille et de voir si la souris sur est vrai sur l'un de ceux-ci et le fossé sur, et encore il ne cesse retourner faux pour tout cela et s'effondrer. Je pensais que IsMouseOver était censé me dire si la souris est terminée, même si ce sont les enfants du contrôle ...

+0

Qu'est-ce que vous ciblez: Winforms, WPF, ASP ..? __Always__ AJOUTEZ correctement votre question! – TaW

+0

IsMouseOver ne sera pas vrai. La gestion normale de la souris est suspendue pendant qu'une opération D + D est en cours. Difficile de voir comment quelqu'un pourrait proposer une alternative à partir de cet extrait. –

+0

Oups, désolé, c'est WPF. Donc, Hans, vous dites qu'il n'y a aucun moyen de dire si la souris est dans les limites de la grille? – sfaust

Répondre

0

Ok, après quelques recherches supplémentaires, j'ai trouvé quelque chose qui semble fonctionner. J'ai fini par devoir utiliser VisualTreeHelper.HitTest et utiliser la surcharge qui a un rappel et obtient tous les éléments touchés même s'il est obscurci. Voici mon code final:

void Grid_DragLeave(object sender, DragEventArgs e) 
    { 
     var wizard = DataContext as WizardVM; 
     var gd = sender as Grid; 

     if (wizard == null || gd == null) return; 
     Point pt = e.GetPosition(this); 
     hitResults.Clear(); 
     VisualTreeHelper.HitTest(gd, null, GridHitTestResultCallback, 
      new PointHitTestParameters(pt)); 

     if (!hitResults.Contains(gd)) 
     { 
      wizard.Assembly.IsExpanded = false; 
     } 
    } 

    HitTestResultBehavior GridHitTestResultCallback(HitTestResult result) 
    { 
     hitResults.Add(result.VisualHit); 
     return HitTestResultBehavior.Continue; 
    } 

Fondamentalement, il obtient le point par rapport à la fenêtre complète, puis appelle HitTest avec ce point et la grille dans l'ensemble je suis en train de travailler. Le rappel remplit une liste de visuels touchés par le test d'atteinte. Dernière la méthode originale vérifie si la grille est dans la liste des hits et sinon elle l'effondre.

Comme une note de côté j'ai aussi changé de .ExpandPreview() et .CollapsePreview() à une propriété .IsExpanded pour des raisons non liées ... ne voulait pas qu'on confondre par ce changement ...