2017-04-12 23 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