我刚刚注意到WPF的TreeView的一些奇怪的行为。我添加了ItemContainerStyle以绑定到我的ViewModel的“IsSelected”和ItemsTemplated以自定义显示我的数据。但现在用户无法再更改所选节点。出于测试目的,我使用ListView和Expander创建了一个类似的UI。此版本作为例外。有关TreeView失败的任何提示吗?
<TreeView ItemsSource="{Binding ElementName=frame, Path=list}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}" >
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate>
<TreeViewItem Header="{Binding}">
<TextBlock Text="{Binding Path= Item.SomeData}"/>
</TreeViewItem>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
编辑:我的数据不是层次结构。我只想在显示列表时获得“折叠”功能。 Item.SomeData不是列表。根据需要显示数据。只有鼠标选择失败!
答案 0 :(得分:3)
TreeViews的工作方式不同。 HierarchicalDataTemplate 中的Items是 TreeViewItems,您在HierarchicalDataTemplate中指定的任何控件都将用作其Header。所以,基本上你指定TreeView中的Items是TreeViewItems,TreeViewItems作为标题!相反,试试这个:
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<Label Content="{Binding}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path= Item.SomeData}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
编辑:我无法重现产生你想要绑定的属性的DataSource,所以我写了一些我自己的简单代码,展示了它是如何工作的。希望您能够根据自己的需求进行调整:
<TreeView ItemsSource="{Binding}" Name="Tree">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}" >
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<Label Content="{Binding Name}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path= SomeData}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
namespace TreeViewSpike
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
List = new List<ItemList>
{
new ItemList
{
Name = "MyList",
Items = new List<Item> {new Item("1"),
new Item("2")}
},
new ItemList
{
Name = "MySecondList",
Items = new List<Item> {new Item("3"),
new Item("4")}
}
};
Tree.DataContext = List;
List[1].IsSelected = true;
}
public List<ItemList> List { get; set; }
}
public class ItemList: INotifyPropertyChanged
{
public string Name{ get; set;}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
if (PropertyChanged != null)
PropertyChanged(this,
new PropertyChangedEventArgs("IsSelected"));
if(_isSelected)
MessageBox.Show(Name + " selected");
}
}
public List<Item> Items { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
public class Item
{
public string SomeData { get; set; }
public Item(string data)
{
SomeData = data;
}
}
}