I have a treeview in which there are selectable items, with subitems which may trigger some code action. When the subitem is clicked, the action should be executed, but the parent item has to remain/become the selected item.
The problem I'm facing is that item are not being deselected properly, causing multiple items to be selected in the treeview.
Here's the xaml for the treeview:
<TreeView Name="Treeview1" Style="{StaticResource vcc_Treeview}" >
<TreeView.ItemTemplate >
<HierarchicalDataTemplate ItemsSource="{Binding Children}" >
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImgSrc}" Style="{StaticResource vcc_TreeviewItemImage}" />
<TextBlock Text="{Binding Description}" Style="{StaticResource vcc_TreeviewItemTextblock}" Foreground="{Binding TextColorBrush}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay, Converter={StaticResource clsBindingDebugger}}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
The clsBindingDebugger does nothing but debug print the converted value and pass through the convert- and convertback value.
Next the somewhat shortened version of the TreeviewItem Class
Public Class MyTreeviewItem
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Event MyTreeviewItem_ExpandedChanged(MTI As MyTreeviewItem, IsExpanded As Boolean)
Public Event MyTreeviewItem_SelectedChanged(MTI As MyTreeviewItem, IsSelected As Boolean)
Public Sub New(Optional Level_ As Integer = 1, Optional ByVal Key_ As String = "")
MyBase.New()
Me.Children = New ObservableCollection(Of MyTreeviewItem)
_Key = Key_
_Level = Level_
End Sub
Private _Level As Integer
Public Property Level As Integer
Get
Level = _Level
End Get
Set(value As Integer)
_Level = value
End Set
End Property
Private _Descr As String = ""
Public Property Description As String
Get
Description = _Descr
End Get
Set(value As String)
_Descr = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Description"))
End Set
End Property
Private _Key As String = ""
Public Property Key As String
Get
Key = _Key
End Get
Set(value As String)
_Key = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Key"))
End Set
End Property
Private _ImgSrc As ImageSource
Public Property ImgSrc As ImageSource
Get
ImgSrc = _ImgSrc
End Get
Set(value As ImageSource)
_ImgSrc = value
End Set
End Property
Private _Children As ObservableCollection(Of MyTreeviewItem)
Public Property Children As ObservableCollection(Of MyTreeviewItem)
Get
Return _Children
End Get
Set(value As ObservableCollection(Of MyTreeviewItem))
_Children = value
End Set
End Property
Private _IsSelected As Boolean
Overloads Property IsSelected As Boolean
Get
Return _IsSelected
End Get
Set(ByVal value As Boolean)
_IsSelected = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("IsSelected"))
RaiseEvent MyTreeviewItem_SelectedChanged(Me, _IsSelected)
End Set
End Property
Private _IsActionItem As Boolean
Overloads Property IsActionItem As Boolean
Get
Return _IsActionItem
End Get
Set(ByVal value As Boolean)
_IsActionItem = value
End Set
End Property
End Class
Finally I trigger the event MyTreeviewItem_SelectedChanged:
Private ReselectingParent As Boolean = False
Private Sub MyTreeviewItem_SelectedChanged(MTI As MyTreeviewItem, IsSelected As Boolean)
Debug.Print(MTI.Description & " Selected = " & IsSelected)
If ReselectingParent Then Exit Sub
If IsSelected Then
'Do some (action) stuff here
If MTI.IsActionItem AndAlso MTI.Parent IsNot Nothing Then
ReselectingParent = True 'to prevent this sub from being executed with the next 2 lines
MTI.IsSelected = False
MTI.Parent.IsSelected = True
ReselectingParent = False
End If
End If
End Sub
Suppose the treeview looks like:
item 1
--Action 1
--Action 2
Item 2
--Action 3
--Action 4
In my starting situation item 2 is selected. Now I click Action 1, so the action should be executed and afterwards item 1 should be the selected item. The debug.print results in these lines:
ConvertBack: False
Item 2 Selected = False
Convert: False
ConvertBack: True
Action 2 Selected = True
Action 2 Selected = False
Convert: True
Item 1 Selected = True
Convert: False
At this point Item 1 is selected, as it should be. Now I click Action 3.
ConvertBack: False
Action 2 Selected = False
Convert: False
ConvertBack: True
Action 3 Selected = True
Action 3 Selected = False
Convert: True
Item 2 Selected = True
Convert: False
The result is that Item 1 and Item 2 are both selected, where only Item 2 should be selected. The second debugger block says "Action 2 Selected = False", this should be "Item 1 Selected = False"
I hope I'm clear. Can anybody point me to the solution of my problem? Thanks!