[英]TreeViewItem IsExpanded with HierarchialDataTemplate
I am trying so set up a TreeView for a Group/User hierarchy, where a group can have users and subgroups, and subgroups also subgroups and users, and so on. 我正在尝试为组/用户层次结构设置一个TreeView,其中一个组可以具有用户和子组,子组也可以具有子组和用户,依此类推。 When I add/remove a user or group from a collection and update the view with myTreeView.Items.Refresh();
当我从集合中添加/删除用户或组并使用myTreeView.Items.Refresh();
更新视图时 all expanded TreeViewItems get closed. 所有展开的TreeViewItems都将关闭。 This is inconvenient for the user, so i am trying to expand all TreeViewItems which were expanded before. 这对用户来说很不方便,所以我正在尝试扩展之前已扩展的所有TreeViewItems。 myTreeView.SelectedItem;
doesn't seem to work, it only returns a Group
or User
Element no TreeViewItem
Element. 似乎不起作用,它仅返回Group
或User
元素,而没有TreeViewItem
元素。 Now, I found something here WPF DataBound treeview expand / collapse that I tried, but the compiler is telling me this now 现在,我在这里找到了我尝试过的WPF DataBound treeview展开/折叠的内容 ,但是编译器现在告诉了我
BindingExpression path error: 'IsNodeExpanded' property not found on 'object' ''User' BindingExpression路径错误:在“对象”“用户”上找不到“ IsNodeExpanded”属性
A User can't be expanded, so implementing this Field in the User class wouldn't make sense. 无法扩展用户,因此在User类中实现此Field毫无意义。 What am I doing wrong? 我究竟做错了什么? Is this even the right approach? 这是正确的方法吗?
I have following setup for my TreeView 我为TreeView进行了以下设置
<TreeView Grid.Column="0" Name="myTreeView" SelectedItemChanged="myTreeView_SelectedItemChanged" MouseDoubleClick="myTreeView_MouseDoubleClick">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type datatypes:Group}" ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}">
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type datatypes:User}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding LicenceUser}"/>
</StackPanel>
</DataTemplate>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsNodeExpanded, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</Style>
</TreeView.Resources>
</TreeView>
For better visibility I only copy the interfaces for my classes here. 为了获得更好的可见性,我仅在此处复制类的接口。
Here the interface for my Group class 这是我的Group类的界面
interface IGroup {
int ID { get; set; }
string Name { get; set; }
string Gruppe { get; set; }
string Path { get; set; }
Users Users { get; set; }
ObservableCollection<object> Items { get; }
bool IsNodeExpanded { get; set; }
Groups SubGroups { get; set; }
}
the Items Collection in the Group class looks like this Group类中的Items Collection看起来像这样
public ObservableCollection<object> Items {
get {
ObservableCollection<object> childItems = new ObservableCollection<object>();
foreach (Group item in SubGroups) {
childItems.Add(item);
}
foreach (User item in Users) {
childItems.Add(item);
}
return childItems;
}
}
and the interface for my User class 和我的User类的界面
interface IUser {
string UserID { get; set; }
string LicenceUser { get; set; }
string MailAddress { get; set; }
string ComputerName { get; set; }
string HardDriveID { get; set; }
string Group { get; set; }
string Path { get; set; }
}
Thanks in advance for your help. 在此先感谢您的帮助。
The setter for IsExpanded
applies to all TreeViewItems
whether they're Users or Groups. IsExpanded
的设置器适用于所有TreeViewItems
无论它们是“用户”还是“组”。 It shouldn't stop you from compiling; 它不应该阻止您进行编译; it'll just give you a bunch of binding errors in the debug output during runtime. 它只会在运行时给您一些调试输出中的绑定错误。
If that's not acceptable, the quickest solution for your case is to make a converter that distinguishes between Users and Groups and returns false for the former (eg IsExpanded="{Binding Path=., Converter={StaticResource ItemToBooleanConverter}}"
) 如果不可接受,针对您的情况,最快的解决方案是使转换器区分用户和组,并为前者返回false(例如IsExpanded="{Binding Path=., Converter={StaticResource ItemToBooleanConverter}}"
)
public class ItemToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is User)
return false;
return ((Group)value).IsNodeExpanded;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
EDIT: This doesn't seem to work for two-way binding. 编辑:这似乎不适用于双向绑定。 What I did in a similar situation was add ITypeProvider
with one Type
property so that I could make the distinction between types in XAML. 我在类似情况下所做的就是添加具有一个Type
属性的ITypeProvider
,以便可以区分XAML中的类型。 A DataTrigger
can set the IsExpanded
binding only for a particular data type. DataTrigger
只能为特定数据类型设置IsExpanded
绑定。 Adds mostly useless bloat to your classes, but it helps you avoid the binding errors. 给您的类增加了大部分无用的膨胀,但是它可以帮助您避免绑定错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.