开发者

Refresh TreeView CollectionViewSource ObservableCollection Item Changed

开发者 https://www.devze.com 2023-02-28 00:21 出处:网络
Hello I have the following setup for a treeview: <local:BuddyManager x:Key=\"bmBuddyManager\" />

Hello I have the following setup for a treeview:

<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=Gro开发者_StackOverflowups}"
                  ItemTemplate="{StaticResource hdtBuddyCategoryTemplate}"
                  ContextMenuOpening="tvBuddies_ContextMenuOpening"
                  ContextMenuClosing="tvBuddies_ContextMenuClosing"
                  Background="Transparent" Margin="2,0,3,3">
        </TreeView>

Code Behind:

<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

How I interact with the classes:

    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)

The Binding and grouping work well, the only issue is when I set a particular 'buddy' to online or blocked the child nodes do not move or change.

I am trying to get this to work like an MSN Treeview where people go offline and online.

Any help is appreciated, I have been working on this problem for a month or so with heavy research and no luck.

Thank you for your time.


Looks like you need an OnPropertyChanged event in the State property for VisualColor. The UI does not get a notification that the visual color should be updated. It knows that the State value has changed, but all that means is whatever is bound to the State property gets updated.

I would suggest putting those colors in XAML and writing a DataTrigger on your item, that evaluates the state and changes the color to suit.

Next as for not moving from one status category to another, when you set the state, have you looked at the CollectionViewSource at runtime to see how it is sorting? Are you calling a refresh on the CVS view anywhere?

0

精彩评论

暂无评论...
验证码 换一张
取 消