2010-07-13 126 views
0

由于我对我的帖子所做的更改,我曾想过打开另一个线程。在新的帖子中,我发布了我的(检验)解决方案。 你可以找到它hereWPF刷新TreeView时失去焦点

嗨! 我的WPF应用程序(Framework 3.5 SP1)中的TreeView出现问题。 这是一个具有2级数据的TreeVIew。我以特定的方式展开/折叠第一层的项目(只需单击鼠标并单击TreeViewItem)。当我展开一级TreeViewItem时,我向该组添加了一些二级TreeViewItems(这是一个重要的细节,事实上,如果我不添加项目,问题不会发生)。所有的作品都很好,直到TreeView失去焦点。 例如,如果我在第一个位置展开TreeViewItem,同时向第二个层次添加一个元素,然后单击一个按钮(让TreeView失去焦点),然后再次单击在TreeViewItem的第三个位置展开它,TreeViewItem不是“真正的”TreeViewItem(在本例中是第三个),而是一个TreeViewItem,它位于比TreeViewItem更高的位置点击(在这里是第二个)。 我试图在TreeView-LostFocus事件上使用UpdateLayout方法,但没有结果。可能我需要一个相反的方法:从UI开始,刷新包含TreeViewItems位置的对象。 你能帮我吗? 谢谢! Pileggi

这是代码:

' 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

我仍然认为这个问题是与你的命中测试代码。它正在查找上一个元素,而不是单击的元素。尝试在'getItemFromMousePosition'中的'While'循环之前添加'Debug.WriteLine(obj Is sender)'行。我猜想它会在点击处理正确时打印为True,在没有正确处理时打印为False。 – Quartermeister 2010-07-14 13:33:47

+0

由于我对我的帖子所做的更改,我曾想过打开另一个主题。在新的帖子中,我发布了我的(检验)解决方案。您可以在这里找到它: http://stackoverflow.com/questions/3245036/wpf-refresh-treeview-when-it-loses-the-focus – lamarmora 2010-07-15 09:07:28

回答

0

由于我对我的帖子所做的更改,我曾想过打开另一个线程。在新的帖子中,我发布了我的(检验)解决方案。你可以找到它here

0

你的命中测试代码,似乎有些奇怪。您忽略MouseButtonEventArgs对象给出的鼠标位置,然后在TreeView中点击控件的左上角进行命中测试。这通常会让你重新获得相同的控制权,并且我怀疑你的怪异行为是在它没有的情况下。不用做TranslatePoint和InputHitTest,直接使用发件人即可。您的辅助函数简化为:

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 

您可以通过采取这一事实的MouseUp是一个路由事件优势,让它找到树型视图父母为你实际上使其更简单一次。除了将事件处理程序添加到TreeView本身之外,还可以将MouseUp处理程序添加到TreeViewItem中,并始终使用TreeViewItem的发件人调用它。

如果还没有,您还应该在IsExpanded上将绑定设置为双向绑定。这样您可以更新TreeViewItem上的IsExpanded,并将该值推送到绑定源。

在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> 

然后在代码:

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

谢谢你,你是很亲切。但不幸的是,问题与您的解决方案相同。 我省略了一个重要的细节(对不起):当我展开一级TreeViewItem时,我添加了一些二级TreeviewItems。这会导致问题,如果我不添加项目所有作品都很好。 我编辑了我的问题,使其更易于理解。 也许现在解决方案更容易(我希望)。 谢谢, Pileggi