0
votes

I have a treeview binded to an Observablecollection of ParentViewModel.

The ParentViewModel contains an Observablecollection of ChildViewModel.

Both this ViewModel implement an IsSelected property. I put it in both of them because the implementation is a little bit different. The program have to behave differently if I press a Parent or Child item.

My problem is that also if I select a Child item, program execute the IsSelected property of the ParentViewModel, not the one of the ChildViewModel.

This is my XAML:

         <TreeView Name="MyTreeView"
        ItemsSource="{Binding ParentList}">

        <TreeView.ItemContainerStyle>
           <Style TargetType="{x:Type TreeViewItem}">
              <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
           </Style>
        </TreeView.ItemContainerStyle>

        <TreeView.Resources>
           <HierarchicalDataTemplate DataType="{x:Type local:ParentViewModel}" ItemsSource="{Binding Childs}">

              <Grid >
                 <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="1*"/>
                 </Grid.ColumnDefinitions>

                 <Image Grid.Column="0" Source="{Binding PictureString}" Height="32" Width="32" Margin="0,8,6,4" />
                 <TextBlock Grid.Column="1" Text="{Binding Name}" FontSize="15" Margin="10" />

              </Grid>

              <HierarchicalDataTemplate.ItemContainerStyle>
                 <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                 </Style>
              </HierarchicalDataTemplate.ItemContainerStyle>

           </HierarchicalDataTemplate>

           <DataTemplate DataType="{x:Type local:ChildViewModel}">
              <Grid >
                 <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="1*"/>
                 </Grid.ColumnDefinitions>

                 <!--<Image Grid.Column="0" Source="{Binding PictureString}" Height="32" Margin="0,8,6,4" />-->
                 <TextBlock Grid.Column="1" Text="{Binding Name}" Height="18" FontSize="15"  Margin="10"/>

              </Grid>
           </DataTemplate>

        </TreeView.Resources>

     </TreeView>

The program never hit the IsSelected setter of the ChildViewModel.

Thanks in advance

EDIT

This is the BaseViewModel:

Public Class InheritableTreeViewItem
   Implements INotifyPropertyChanged

   Friend m_Name As String
   Public Property Name As String
      Get
         Return m_Name
      End Get
      Set(value As String)
         If (value <> m_Name) Then
            m_Name = value
            NotifyPropertyChanged("Name")
         End If
      End Set
   End Property

   Friend m_IsSelected As Boolean
   Public Overridable Property IsSelected As Boolean
      Get
         Return m_IsSelected
      End Get
      Set(value As Boolean)
         If (value <> m_IsSelected) Then
            m_IsSelected = value
            NotifyPropertyChanged("IsSelected")
         End If
      End Set
   End Property


   Private m_sPictureString As String
   Private m_Items As ObservableCollection(Of InheritableTreeViewItem)

   Public Property PictureString As String
      Get
         Return m_sPictureString
      End Get
      Set(value As String)
         If value <> m_sPictureString Then
            m_sPictureString = value
            NotifyPropertyChanged("PictureString")
         End If
      End Set
   End Property

   Public Property Items As ObservableCollection(Of InheritableTreeViewItem)
      Get
         Return m_Items
      End Get
      Set(value As ObservableCollection(Of InheritableTreeViewItem))
         m_Items = value
      End Set
   End Property

   Sub New(Name As String)
      Me.Name = Name
      Me.Items = New ObservableCollection(Of InheritableTreeViewItem)
   End Sub

   Public Event PropertyChanged As PropertyChangedEventHandler Implements    INotifyPropertyChanged.PropertyChanged

   Public Sub NotifyPropertyChanged(propName As String)
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
   End Sub


End Class

And this is the ParentViewModel:

Public Class ParentViewModel
   Inherits InheritableTreeViewItem

   Public Overrides Property IsSelected As Boolean
      Get
         Return m_IsSelected
      End Get
      Set(value As Boolean)
         If (value <> m_IsSelected) Then
            m_IsSelected = value
            If value Then
               ' The function that I want to call When Parent item is selected in the tree
            End If
            NotifyPropertyChanged("IsSelected")
         End If
      End Set
   End Property

   Sub New(Name As String)
      MyBase.New(Name)
      Me.PictureString = "/Resources/TreeView/Folder.png"
   End Sub

End Class

The ChildViewModel is basically identical, it differs only for the function that I call when it is selected. This function modify the content and visibility of some TextBoxes.

1
Post viewmodel code.Ayyappan Subramanian
I posted it. But I think the error must be in the XAML binding, because all the treeview element is correctly displayed.Emmanuele

1 Answers

0
votes

I think your problem is at this block :

<TreeView.ItemContainerStyle>
    <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
    </Style>
</TreeView.ItemContainerStyle>

Because it is a style, I'm not sure that the DataContext is properly inherited. Also why do you redefine this in the HierarchicalDataTemplate? I don't think you need to redefine this style for ChildViewModelItems.

Maybe you could debug your databinding in depth to see what's happening on this property : How to debug data binding.

Also, the plural of Child is Children, not Childs ;)