2014-06-17 82 views
0

我有一個基於MVVM軟件架構的WPF應用程序。它由treeView和ListView組成。當單擊treeView節點時,該節點的所有子節點都顯示在列表視圖中。我能夠實現這一部分。WPF MVVM:從ListView中選擇TreeViewItem

但是當用戶點擊listView中的某個項目時,應該在treeView中選擇該特定項目(它是樹視圖中的一個節點)。我不知道如何做到這一點。 基本上我想要將屬性SelectedItem綁定到listview選定的項目。但似乎treeview selectedItem propeerty是隻讀的。

<TreeView Name="tv" ItemsSource="{Binding ChildAndAttributes}" VerticalAlignment="Stretch" Margin="12,12,12,35"> 
     <TreeView.Resources> 
      <DataTemplate DataType="{x:Type tvcc:NodeViewModel}"> 
       <TextBlock Text="{Binding Text}" /> 
      </DataTemplate> 
      <DataTemplate DataType="{x:Type tvcc:NodeAttributeViewModel}"> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding AttributeName}" /> 
        <TextBlock Text="{Binding AttributeValue}" Padding="2,0,0,0" Foreground="Blue" /> 
       </StackPanel> 
      </DataTemplate> 
     </TreeView.Resources> 
     <TreeView.ItemTemplate> 
      <HierarchicalDataTemplate ItemsSource="{Binding ChildAndAttributes}"> 
       <ContentControl Content="{Binding}" /> 
      </HierarchicalDataTemplate> 
     </TreeView.ItemTemplate> 
    </TreeView> 

回答

0

下面是一些擴展樹https://stackoverflow.com/a/18265571/634219,允許你綁定樹的selectedItem屬性:

public class TreeViewEx : TreeView 
{ 
    public TreeViewEx() 
    { 
     SelectedItemChanged += TreeViewEx_SelectedItemChanged; 
    } 

    void TreeViewEx_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) 
    { 
     SelectedItem = e.NewValue; 
    } 

    #region SelectedItem 

    /// <summary> 
    /// Gets or Sets the SelectedItem possible Value of the TreeViewItem object. 
    /// </summary> 
    public new object SelectedItem 
    { 
     get { return GetValue(SelectedItemProperty); } 
     set { SetValue(SelectedItemProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc... 
    public new static readonly DependencyProperty SelectedItemProperty = 
     DependencyProperty.Register("SelectedItem", typeof(object), typeof(TreeViewEx), new PropertyMetadata(SelectedItemProperty_Changed)); 

    static void SelectedItemProperty_Changed(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
    { 
     var targetObject = dependencyObject as TreeViewEx; 
     if (targetObject != null) 
     { 
      var tvi = targetObject.FindItemNode(targetObject.SelectedItem); 
      if (tvi != null) 
       tvi.IsSelected = true; 
     } 
    } 
    #endregion SelectedItem 

    public TreeViewItem FindItemNode(object item) 
    { 
     TreeViewItem node = null; 
     foreach (object data in Items) 
     { 
      node = ItemContainerGenerator.ContainerFromItem(data) as TreeViewItem; 
      if (node != null) 
      { 
       if (data == item) 
        break; 
       node = FindItemNodeInChildren(node, item); 
       if (node != null) 
        break; 
      } 
     } 
     return node; 
    } 

    protected TreeViewItem FindItemNodeInChildren(TreeViewItem parent, object item) 
    { 
     TreeViewItem node = null; 
     bool isExpanded = parent.IsExpanded; 
     if (!isExpanded) //Can't find child container unless the parent node is Expanded once 
     { 
      parent.IsExpanded = true; 
      parent.UpdateLayout(); 
     } 
     foreach (object data in parent.Items) 
     { 
      node = parent.ItemContainerGenerator.ContainerFromItem(data) as TreeViewItem; 
      if (data == item && node != null) 
       break; 
      node = FindItemNodeInChildren(node, item); 
      if (node != null) 
       break; 
     } 
     if (node == null && parent.IsExpanded != isExpanded) 
      parent.IsExpanded = isExpanded; 
     if (node != null) 
      parent.IsExpanded = true; 
     return node; 
    } 
} 
0

一個選擇TreeViewItemTreeView是將數據綁定到TreeViewItem.IsSelected Property最簡單的方法。這確實意味着你將不得不添加一個額外的bool IsSelected屬性到你的數據類型類,但它會讓你從視圖模型中選擇任何項目。您可以將數據綁定到這個屬性在Style

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

或者,您也可能希望將數據綁定到TreeViewItem.IsExpanded Property了,所以你可以選擇從視圖模型展開相關項目:

YourDataType item = Items.First(i => i.Id == someValue); 
item.IsSelected = true; 
item.IsExpanded = true;