2010-07-13 7 views
0

En raison des modifications que j'ai apportées à mon message, j'ai pensé à ouvrir un autre sujet. Dans le nouveau fil, j'ai posté ma solution (provisoire). Vous pouvez le trouver hereWPF actualise TreeView lorsqu'il perd le focus

Hi! J'ai un problème avec mon TreeView dans une application WPF (Framework 3.5 SP1). C'est un TreeVIew avec 2 niveaux de données. Je développe/réduit les éléments du premier niveau d'une manière particulière (avec un simple clic de souris sur le TreeViewItem). Encore une fois quand je développe un TreeViewItem de premier niveau, j'ajoute des TreeViewItems de second niveau au groupe (c'est un détail important, en fait, si je n'ajoute pas les éléments, le problème ne se produit pas). Tout fonctionne bien jusqu'à ce que le TreeView perd son focus. Si, par exemple, je développe le TreeViewItem à la première position, en ajoutant en même temps un élément au deuxième niveau, puis je clique sur un bouton (pour laisser le TreeView perdre le focus), puis je clique à nouveau sur le TreeViewItem à la troisième position pour l'agrandir, le TreeViewItem qui résulte du hit-test avec la position de la souris n'est pas le "vrai" TreeViewItem (dans ce cas le troisième), mais un TreeViewItem qui est dans une position plus élevée que celle cliqué (dans ce cas, le second). J'ai essayé d'utiliser la méthode UpdateLayout sur l'événement TreeView-LostFocus, mais sans résultats. Probablement j'ai besoin d'une méthode qui fait le contraire: à partir de l'interface utilisateur, actualisez l'objet qui contient la position de TreeViewItems. Pouvez-vous, s'il vous plaît, m'aider? Merci! Pileggi

Voici le code:

' in this way I tried to put remedy at the problem, but it doesn't work. 
    Private Sub tvArt_LostFocus(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles tvArt.LostFocus 
     Me.tvArt.UpdateLayout() 

     e.Handled = True 
    End Sub 

    ' here I expand/collapse the items of the first level of my TreeView 
    Private Sub tvArt_PreviewMouseUp(ByVal sender As System.Object, ByVal e As MouseButtonEventArgs) Handles tvArt.PreviewMouseUp 
     Dim p As Point = Nothing 
     Dim tvi As TreeViewItem = getItemFromMousePosition(Of TreeViewItem)(p, e.OriginalSource, Me.tvArt) 
     If tvi Is Nothing = False Then 
      If tvi.HasItems Then 
       Dim be As BindingExpression = BindingOperations.GetBindingExpression(tvi, TreeViewItem.ItemsSourceProperty) 
       Dim ri As P_RicambiItem = DirectCast(be.DataItem, P_RicambiItem) 
       If ri.isExpanded = False then 
        ' here I add items to the second level collection 
       End If 
       ri.isExpanded = Not ri.isExpanded 
      End If 
     End If 

     e.Handled = True 
    End Sub 

    Private Function getItemFromMousePosition(Of childItem As DependencyObject)(ByRef p As Point, ByVal sender As UIElement, _ 
     ByVal _item As UIElement) As childItem 

     p = sender.TranslatePoint(New Point(0, 0), _item) 
     Dim obj As DependencyObject = DirectCast(_item.InputHitTest(p), DependencyObject) 
     While obj Is Nothing = False AndAlso TypeOf obj Is childItem = False 
      obj = VisualTreeHelper.GetParent(obj) 
     End While 
     Return DirectCast(obj, childItem) 
    End Function 
+0

Je pense toujours que le problème est avec votre code de test. C'est trouver l'élément précédent à la place du clic. Essayez d'ajouter la ligne 'Debug.WriteLine (obj Is sender)' avant la boucle 'While' dans' getItemFromMousePosition'. Je suspecte qu'il imprimera vrai quand le clic est manipulé correctement et Faux quand ce n'est pas fait. – Quartermeister

+0

En raison des changements que j'ai faits à mon poste, j'ai pensé ouvrir un autre fil. Dans le nouveau fil, j'ai posté ma solution (provisoire). Vous pouvez le trouver ici: http://stackoverflow.com/questions/3245036/wpf-refresh-treeview-when-it-loses-the-focus – lamarmora

Répondre

0

En raison des changements que j'ai faits à mon poste, j'ai pensé à ouvrir un autre fil. Dans le nouveau fil, j'ai posté ma solution (provisoire).Vous pouvez le trouver here

0

Votre code de test de recherche semble un peu bizarre. Vous ignorez la position de la souris donnée par l'objet MouseButtonEventArgs, puis effectuez un test d'impact dans TreeView dans le coin supérieur gauche du contrôle sur lequel vous avez cliqué. Cela vous redonnera normalement le même contrôle, et je soupçonne que votre comportement étrange est dans les cas où ce n'est pas le cas. Au lieu de faire TranslatePoint et InputHitTest, utilisez simplement l'expéditeur directement. Votre fonction d'aide se réduit à:

Private Function getParentOfType(Of childItem As DependencyObject)(ByVal sender As UIElement) As childItem 
    Dim obj As DependencyObject = sender 
    While obj Is Nothing = False AndAlso TypeOf obj Is childItem = False 
     obj = VisualTreeHelper.GetParent(obj) 
    End While 
    Return DirectCast(obj, childItem) 
End Function 

Vous pouvez réellement le rendre plus simple à nouveau en tirant profit du fait que MouseUp est un événement routé et de le laisser trouver le parent TreeViewItem pour vous. Au lieu d'ajouter le gestionnaire d'événements à TreeView lui-même, ajoutez un gestionnaire MouseUp à TreeViewItem, et il sera toujours appelé avec un expéditeur de TreeViewItem.

Vous devez également définir votre liaison sur IsExpanded pour être bidirectionnelle si ce n'est déjà fait. De cette façon, vous pouvez mettre à jour IsExpanded sur TreeViewItem et la valeur sera transmise à la source de liaison.

En XAML:

<TreeView.ItemContainerStyle> 
    <Style TargetType="{x:Type TreeViewItem}"> 
     <Setter Property="IsExpanded" Value="{Binding isExpanded, Mode=TwoWay}" /> 
     <EventSetter Event="Mouse.MouseUp" Handler="tvi_MouseUp"/> 
    </Style> 
</TreeView.ItemContainerStyle> 

Puis dans le code:

Private Sub tvi_MouseUp(ByVal sender As System.Object, ByVal e As MouseButtonEventArgs) 
    Dim tvi As TreeViewItem = DirectCast(sender, TreeViewItem) 
    If tvi.HasItems Then 
     tvi.IsExpanded = Not tvi.IsExpanded 
    End If 
    e.Handled = True 
End Sub 
0

Merci, vous êtes très gentil. Mais malheureusement, le problème est le même avec votre solution. J'ai omis un détail important (désolé): lorsque j'élargis un TreeViewItem de premier niveau, j'ajoute des TreeviewItems de second niveau. Cela provoque le problème, si je n'ajoute pas les éléments tout fonctionne bien. J'ai édité ma question pour la rendre plus compréhensible. Peut-être que maintenant la solution est plus facile (j'espère). Merci, Pileggi

Questions connexes