我有一个基于MVVM软件架构的wpf应用程序。它由treeView和ListView组成。单击treeView节点时,该节点的所有子节点都将显示在列表视图中。我能够实现这一部分。
但是当用户单击listView中的某个项目时,应该在treeView中选择该特定项目(树视图中的节点)。我不知道该怎么做。 基本上我想将属性SelectedItem绑定到listview所选项。但看起来像treeview selectedItem propeerty是readonly。
<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 :(得分:0)
以下是树https://stackoverflow.com/a/18265571/634219的一些扩展,它允许您绑定树的选定项:
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;
}
}
答案 1 :(得分:0)
在TreeViewItem
中选择TreeView
的最简单方法之一是将数据绑定到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;