2011-04-23 139 views
2

你好,我有一个TreeView以下设置:刷新TreeView的CollectionViewSource的ObservableCollection项目已更改

<local:BuddyManager x:Key="bmBuddyManager" /> 

<CollectionViewSource x:Key="cvsBuddyManager" 
         Source="{Binding Source={StaticResource bmBuddyManager}, Path=Buddies}"> 
    <CollectionViewSource.GroupDescriptions> 
     <PropertyGroupDescription PropertyName="State" /> 
    </CollectionViewSource.GroupDescriptions> 
</CollectionViewSource> 

<DataTemplate x:Key="dtBuddyTemplate" DataType="{x:Type local:Buddy}"> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock Text="{Binding Nick}" FontSize="12" FontWeight="Bold" /> 
     <TextBlock Text="{Binding GameHost}" FontSize="12" FontWeight="Bold" 
        Foreground="Purple" Margin="10,0,0,0" /> 
    </StackPanel> 
</DataTemplate> 

<HierarchicalDataTemplate x:Key="hdtBuddyCategoryTemplate" ItemsSource="{Binding Path=Items}" 
          ItemTemplate="{StaticResource dtBuddyTemplate}"> 
    <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Foreground="Gold" FontSize="15" /> 
</HierarchicalDataTemplate> 

     <TreeView ItemsSource="{Binding Source={StaticResource cvsBuddyManager}, Path=Groups}" 
        ItemTemplate="{StaticResource hdtBuddyCategoryTemplate}" 
        ContextMenuOpening="tvBuddies_ContextMenuOpening" 
        ContextMenuClosing="tvBuddies_ContextMenuClosing" 
        Background="Transparent" Margin="2,0,3,3"> 
     </TreeView> 

代码背后:

<System.Runtime.InteropServices.ComVisible(False)> Public Enum BuddyState 
    Online 
    Offline 
    Blocked 
End Enum 

<System.Runtime.InteropServices.ComVisible(False)> Public Class Buddy 
    Implements INotifyPropertyChanged 

    Private _Nick As String 
    Private _IsInGame As Boolean 
    Private _GameHost As String 
    Private _State As BuddyState 

    Sub New(ByVal xwisNick As String) 
     _Nick = xwisNick 
     _State = BuddyState.Offline 
    End Sub 

    Sub New(ByVal xwisNick As String, ByVal state As BuddyState) 
     _Nick = xwisNick 
     _State = state 
    End Sub 

    Public Property Nick() As String 
     Get 
      Return _Nick 
     End Get 
     Set(ByVal value As String) 
      _Nick = value 
     End Set 
    End Property 

    Public Property IsInGame() As Boolean 
     Get 
      Return _IsInGame 
     End Get 
     Set(ByVal value As Boolean) 
      _IsInGame = value 

      If _IsInGame = False Then 
       GameHost = Nothing 
      End If 

      OnPropertyChanged("IsInGame") 
     End Set 
    End Property 

    Public Property GameHost() As String 
     Get 
      Return _GameHost 
     End Get 
     Set(ByVal value As String) 
      _GameHost = value 
      OnPropertyChanged("GameHost") 
     End Set 
    End Property 

    Public Property State() As BuddyState 
     Get 
      Return _State 
     End Get 
     Set(ByVal value As BuddyState) 
      _State = value 

      If value = BuddyState.Online Then 
       If _IsInGame Then 
        _IsInGame = False 
        _GameHost = Nothing 
       End If 
      End If 

      OnPropertyChanged("State") 
     End Set 
    End Property 

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 

    ' Create the OnPropertyChanged method to raise the event 
    Protected Sub OnPropertyChanged(ByVal name As String) 
     Try 
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name)) 
     Catch 
     End Try 
    End Sub 
End Class 

Public Class BuddyManager 
    Implements INotifyPropertyChanged 

    Private ocBuddies As ObservableCollection(Of Buddy) = New ObservableCollection(Of Buddy) 

    Public ReadOnly Property Buddies As ObservableCollection(Of Buddy) 
     Get 
      Return ocBuddies 
     End Get 
    End Property 

    Public BuddyCheck As List(Of Buddy) = New List(Of Buddy) 
    Public IsCheckingForBuddies As Boolean = False 


    Public Function IsBuddy(ByVal XwisNick As String) As Boolean 
     Dim nick As String = XwisNick.ToLower 

     For Each b As Buddy In ocBuddies 
      If b.Nick = nick Then 
       Return True 
      End If 
     Next 

     Return False 
    End Function 

    Public Function IsInGame(ByVal XwisNick As String) As String 
     Dim nick As String = XwisNick.ToLower 

     For Each b As Buddy In ocBuddies 
      If b.Nick = nick Then 
       If b.IsInGame Then 
        Return b.GameHost 
       Else 
        Return Nothing 
       End If 
      End If 
     Next 

     Return Nothing 
    End Function 


    Public Function AddBuddy(ByVal XwisNick As String) As Boolean 
     Dim nick As String = XwisNick.ToLower 

     For Each b As Buddy In ocBuddies 
      If b.Nick = nick Then 
       Return False 
      End If 
     Next 

     ocBuddies.Add(New Buddy(nick)) 

     OnPropertyChanged("Buddies") 

     Return True 
    End Function 

    Public Function RemoveBuddy(ByVal XwisNick As String) As Boolean 
     Dim nick As String = XwisNick.ToLower 

     For i As Integer = 0 To ocBuddies.Count - 1 
      If ocBuddies(i).Nick = nick Then 
       ocBuddies.RemoveAt(i) 

       OnPropertyChanged("Buddies") 

       Return True 
      End If 
     Next 

     Return False 
    End Function 

    Public Function BlockBuddy(ByVal XwisNick As String) As Boolean 
     Dim nick As String = XwisNick.ToLower 

     For i As Integer = 0 To ocBuddies.Count - 1 
      If ocBuddies(i).Nick = nick Then 
       ocBuddies(i).State = BuddyState.Blocked 

       OnPropertyChanged("Buddies") 

       Return True 
      End If 
     Next 

     ocBuddies.Add(New Buddy(nick, BuddyState.Blocked)) 

     OnPropertyChanged("Buddies") 

     Return True 
    End Function 

    Public Function UnblockBuddy(ByVal XwisNick As String) As Boolean 
     Dim nick As String = XwisNick.ToLower 

     For i As Integer = 0 To ocBuddies.Count - 1 
      If ocBuddies(i).Nick = nick Then 
       ocBuddies(i).State = BuddyState.Offline 

       OnPropertyChanged("Buddies") 

       Return True 
      End If 
     Next 

     Return False 
    End Function 


    Public Sub UpdateOnlineStatus(ByVal XwisNick As String, ByVal online As Boolean) 
     Dim nick As String = XwisNick.ToLower 

     For i As Integer = 0 To ocBuddies.Count - 1 
      If ocBuddies(i).Nick = nick Then 
       If online Then 
        ocBuddies(i).State = BuddyState.Online 
       Else 
        ocBuddies(i).State = BuddyState.Offline 
       End If 
       OnPropertyChanged("Buddies") 

       Exit For 
      End If 
     Next 

     RaiseEvent BuddyOnlineStatusChanged(nick, online) 
    End Sub 

    Public Sub UpdateInGameStatus(ByVal XwisNick As String, ByVal gamehost As String) 
     Dim nick As String = XwisNick.ToLower 

     For i As Integer = 0 To ocBuddies.Count - 1 
      If ocBuddies(i).Nick = nick Then 
       ocBuddies(i).IsInGame = True 
       ocBuddies(i).GameHost = gamehost 

       OnPropertyChanged("Buddies") 

       RaiseEvent BuddyGameStatusChanged(nick, gamehost) 

       Exit For 
      End If 
     Next 
    End Sub 


    Public Sub FillBuddyCheck() 
     BuddyCheck = ocBuddies.Where(Function(bud) bud.State <> BuddyState.Blocked).ToList 
    End Sub 

    Public Function GetBuddies() As IEnumerable(Of Buddy) 
     Return ocBuddies.Where(Function(bud) bud.State <> BuddyState.Blocked) 
    End Function 

    Public Sub Sort() 
     ocBuddies.OrderBy(Function(bud) bud.Nick) 
     OnPropertyChanged("Buddies") 
    End Sub 

    Public Function Count() As Integer 
     Return GetBuddies.Count 
    End Function 


    Public Event BuddyOnlineStatusChanged(ByVal nick As String, ByVal online As Boolean) 
    Public Event BuddyGameStatusChanged(ByVal nick As String, ByVal gamehost As String) 


    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 

    ' Create the OnPropertyChanged method to raise the event 
    Protected Sub OnPropertyChanged(ByVal name As String) 
     Try 
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name)) 
     Catch 

     End Try 
    End Sub 
End Class 

如何与类交互:

Public Function GetBuddyManager() As BuddyManager 
     Try 
      Return DirectCast(FindResource("bmBuddyManager"), BuddyManager) 
     Catch ex As Exception 
      MessageBox.Show("Error getting buddy manager object: " & ex.ToString()) 
      Application.Current.Shutdown() 

      Return Nothing 
     End Try 
    End Function 

GetBuddyManager().UpdateOnlineStatus(GetBuddyManager().BuddyCheck(0).Nick, True) 

绑定和分组运行良好,唯一的问题是当我设置一个特定的“伙伴”在线或阻止子节点不移动或改变。

我试图让这个工作像MSN树视图在哪里人们下线和在线。

任何帮助表示赞赏,我一直在研究这个问题一个月左右的研究和重大研究,没有运气。

谢谢你的时间。

+1

3个问题:1:是否有一个原因,你使用的是TreeView而不是ListBox.GroupStyle的ListBox?第二:你是否曾尝试将collectionchanged事件处理程序添加到CollectionViewSource.View或CollectionViewSource.View.Groups [0]以查看它们是否实际上正在更改?第3:UI是否更新并显式调用CollectionViewSource.View.Refresh? – 2011-04-27 19:08:21

+0

第三:是的,我的标签更新(因为我有作为每个项目的堆叠面板中的第二个标签的状态)。第二:CollectionViewSource.View没有任何我能看到的事件。第一:我会尝试。 谢谢! – tcables 2011-04-27 19:11:27

回答

0

看起来您需要VisualColor的State属性中的OnPropertyChanged事件。用户界面没有收到应该更新视觉颜色的通知。它知道国家的价值已经发生了变化,但所有这一切意味着国家财产的更新必然会发生。

建议将这些颜色放在XAML中,并在您的物品上写入一个DataTrigger,以评估状态并更改颜色以适合该颜色。

接下来,当您设置状态时,您是否在运行时查看了CollectionViewSource,看看它是如何排序的?你是否在CVS视图上调用刷新?

+0

我从这个例子中删除了这个。由于这完全不是我的问题或问题所在,但至少感谢你看我的问题。 – tcables 2011-04-28 03:49:31

+0

当你改变属性的时候,你会问为什么你的物品在树形视图中没有改变位置?如果更改State属性,执行OnPropertyChanged并刷新CollectionView,会发生什么情况?没有?就我个人而言,我还没有尝试过这样的实施。在深入研究treeviews和CollectionViewSource之前,我选择了MVVM。然而,我已经得到了这个与视图模型一起工作,并没有很多。在那种情况下,我有几个可观察的集合在某些“国家”中持有对象,我会来回移动物品。像魅力一样工作。 – CodeWarrior 2011-04-28 04:10:50

+0

“更改状态属性,执行OnPropertyChanged并刷新CollectionView”前几天我尝试过,它确实有效 - 但会导致树闪烁,关闭并松动所选项目。在使用上下文菜单或点击删除等选定项目时,会变得非常烦人。 – tcables 2011-04-28 16:04:34

相关问题