刷新TreeView CollectionViewSource ObservableCollection项目已更改

时间:2011-04-23 03:23:09

标签: wpf vb.net treeview 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 Treeview一样工作,让人们离线和上网。

任何帮助表示赞赏,我一直在研究这个问题已经有一个月左右的时间进行了大量的研究而没有运气。

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

看起来在VisualColor的State属性中需要一个OnPropertyChanged事件。 UI不会收到应更新视觉颜色的通知。它知道状态值已经改变,但所有这意味着任何绑定到State属性的东西都会被更新。

建议将这些颜色放在XAML中并在您的项目上编写DataTrigger,以评估状态并更改颜色以适应。

接下来,为了不从一个状态类别移动到另一个状态类别,当您设置状态时,是否在运行时查看了CollectionViewSource以查看它是如何排序的?你在任何地方的CVS视图上调用刷新了吗?