使用不同的viewmodel选择Treeview

时间:2016-07-26 14:07:33

标签: wpf vb.net xaml mvvm treeview

我有一个绑定到ParentViewModel的Observablecollection的树视图。

ParentViewModel包含一个Observablecollection of ChildViewModel。

此ViewModel都实现了IsSelected属性。我把它放在它们两个中因为实现有点不同。如果我按下父项或子项,程序必须有不同的行为。

我的问题是,如果我选择子项,程序也会执行ParentViewModel的IsSelected属性,而不是ChildViewModel的属性。

这是我的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>

该程序从未命中ChildViewModel的IsSelected setter。

提前致谢

修改

这是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

这是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

ChildViewModel基本相同,它仅在我选择时调用的函数不同。此函数修改某些TextBox的内容和可见性。

1 个答案:

答案 0 :(得分:0)

我认为你的问题出在这个街区:

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

因为它是一种样式,我不确定DataContext是否被正确继承。另外,为什么要在HierarchicalDataTemplate中重新定义它?我认为您不需要为ChildViewModelItems重新定义此样式。

也许你可以深入调试你的数据绑定,看看这个属性上发生了什么:How to debug data binding

此外,儿童的复数是儿童,而不是儿童;)