2017-04-12 74 views
2

我试图让所选TreeView节点内部视图模型获取TreeView控件的SelectedItem内部视图模型

里面的XAML

<Grid> 
     <TreeView ItemsSource="{Binding TreeViewModel.TreeData}"> 
      <TreeView.Resources> 
       <HierarchicalDataTemplate ItemsSource="{Binding GroupTables}" DataType="{x:Type tbl:StaticTablesGroup}"> 
        <Label Content="{Binding Name}"/> 

       </HierarchicalDataTemplate> 

       <DataTemplate DataType="{x:Type tbl:GroupTable}"> 
        <Label Content="{Binding Name}"/> 
       </DataTemplate> 
      </TreeView.Resources> 

      <TreeView.ItemContainerStyle> 
       <Style TargetType="TreeViewItem"> 
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> 
        <Style.Triggers> 
         <Trigger Property="IsSelected" Value="True"> 
          <Setter Property="FontWeight" Value="Bold" /> 
         </Trigger> 
        </Style.Triggers> 
       </Style> 
      </TreeView.ItemContainerStyle> 
     </TreeView>   
    </Grid> 

内VieModel

public class TreeTablesViewModel : ViewModelBase 
    { 
     private TablesXML _tables; 
     public TreeTablesViewModel() 
     { 

      _tables = Deserialize.GuymasterXml(); 
     } 

     public List<StaticTablesGroup> TreeData 
     { 
      get 
      { 
       return _tables.StaticTablesGroups; 
      } 

      set 
      { 
       _tables.StaticTablesGroups = value; 
       OnPropertyChanged("TreeData"); 
      } 
     }  
    } 

,最后的数据类

[XmlRoot("Tables")] 
    public class TablesXML 
    { 
     public TablesXML() 
     { 
      StaticTablesGroups = new List<StaticTablesGroup>(); 
     } 


     [XmlArray("StaticGroups")] 
     [XmlArrayItem("StaticGroup", typeof(StaticTablesGroup))] 
     public List<StaticTablesGroup> StaticTablesGroups { get; set; } 

    } 

    public class StaticTablesGroup 
    { 
     public StaticTablesGroup() 
     { 
      GroupTables = new List<GroupTable>(); 
     } 

     [XmlAttribute("Name")] 
     public string Name { get; set; } 

     //[XmlArray("StaticGroup")] 
     [XmlElement("Table", typeof(GroupTable))] 
     public List<GroupTable> GroupTables { get; set; } 


    } 


    public class GroupTable 
    { 

     [XmlElement("TableName")] 
     public string Name { get; set; } 
     [XmlElement("TableTag")] 
     public string Tag { get; set; } 

     private bool _isSelected; 
     public bool IsSelected 
     { 
      get { return _isSelected; } 
      set 
      { 
       if (_isSelected != value) 
       { 
        _isSelected = value; 

       } 
      } 
     } 
    } 

选择Treeview节点后,在GroupTable或StaticTablesGroup中引发IsSelected。 如何获取TreeTablesViewModel中的选定节点?

谢谢

回答

1

您不应该尝试在视图模型中操作视图对象(TreeView,TreeViewItem,TreeNode等)。您查看模型必须只处理业务/ poco对象。

如果要中检索对应于所选择的视觉对象(树型视图或节点)底层业务对象,就可以使用像这样的一个问题:

public class TreeviewSelectedItemTracker 
{ 
    public static TreeTablesViewModel GetSelectedItemHolder(DependencyObject obj) 
    { 
     return (TreeTablesViewModel)obj.GetValue(SelectedItemHolderProperty); 
    } 

    public static void SetSelectedItemHolder(DependencyObject obj, TreeTablesViewModel value) 
    { 
     obj.SetValue(SelectedItemHolderProperty, value); 
    } 

    public static readonly DependencyProperty SelectedItemHolderProperty = 
     DependencyProperty.RegisterAttached("SelectedItemHolder", typeof(TreeTablesViewModel), typeof(TreeviewSelectedItemTracker), new PropertyMetadata(null, OnSelectedChanged)); 

    private static void OnSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     TreeView tv = (TreeView)d; 
     tv.Loaded += Tv_Loaded; 
    } 

    private static void Tv_Loaded(object sender, RoutedEventArgs e) 
    { 
     TreeView tv = (TreeView)sender; 
     tv.Loaded -= Tv_Loaded; 
     tv.Unloaded += Tv_Unloaded; 
     tv.SelectedItemChanged += Tv_SelectedItemChanged; 
    } 

    private static void Tv_Unloaded(object sender, RoutedEventArgs e) 
    { 
     TreeView tv = (TreeView)sender; 

     tv.Unloaded -= Tv_Unloaded; 
     tv.SelectedItemChanged -= Tv_SelectedItemChanged; 
    } 

    private static void Tv_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) 
    { 
     TreeView tv = (TreeView)sender; 

     var cotr = GetSelectedItemHolder(tv); 

     cotr.SelectedItem = tv.SelectedItem; 

    } 
} 

TreeView.SelectedItem直接返回相关联的业务对象选中TreeviewItem

在XAML中,使用附加属性的SelectedItemHolder绑定到视图模型

<TreeView ItemsSource="{Binding TreeViewModel.TreeData}" local:TreeviewSelectedItemTracker.SelectedItemHolder="{Binding}"/> 
+0

后面添加代码,谢谢您的答复。我将Selecteditem属性添加到TreeTablesViewModel:private object _selectedItem; 公共对象SelectedItem { 得到 { return _selectedItem; } set { _selectedItem = value; OnPropertyChanged(“SelectedItem”); } }但是,viewModel内部的SelectedItem从不执行。我究竟做错了什么。 – Vadim

+0

在XAML: Vadim

+0

做你试图将一个破发点的SelectedItemChanged处理程序中的行为,看是否该事件得到提高? – Bruno

0

得到树型视图(这是我想你的意思),是从在树中选择处理程序的项目容器发生器得到它最简单的方法。

private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) 
    { 
     TreeView tv = e.Source as TreeView; 
     TreeViewItem tvi = tv.ItemContainerGenerator.ContainerFromItem(e.NewValue) as TreeViewItem; 
    } 

的XAML

<TreeView ItemsSource="{Binding TreeViewModel.TreeData}" SelectedItemChanged="treeView_SelectedItemChanged" > 

在这里,我想你可以向视图模型。

+0

我尽量不使用MVVM模式 – Vadim