我的模型类看起来像这样:
class Base
{
public string Name { get; set; }
}
class Item : Base { ... }
class Group : Base
{
public List<Base> GroupItems { get; private set; }
}
然后,我有一个带有Items
集合的视图模型,我填写如下FillUp()
方法中所示:
class ViewModel : INotifyPropertyChanged
{
public ObservableCollection<Base> Items { get; set; }
private void FillUp()
{
Item item1 = new Item { Name = "Item1" };
Item item2 = new Item { Name = "Item2" };
Group group = new Group { Name = "Group" };
group.GroupItems.Add(item1);
this.Items.Add(item1);
this.Items.Add(item2);
this.Items.Add(group);
}
}
因此,我的Items
集合现在包含2个类型为Item
的对象和一个类型为Group
的对象,其中包含对{{1}之一的“父子”引用对象。
我想要实现的目标:我想在Item
中显示此模型,以便属于某些TreeView
的所有Item
都应显示为子元素Group
,尽管它们属于“根”集合。
它应该是这样的:
Group
我可以使用- Item2
+ Group
- Item1
来显示父子元素,但这不允许我从根集合中过滤掉属于某些组的那些项目。
HierarchicalDataTemplate
有了这个观点,我得到<TreeView>
<TreeView.Resources>
<HierarchicalDataTemplate DataType = "{x:Type loc:Group}" ItemsSource = "{Binding GroupItems}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type loc:Item}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</TreeView.Resources>
<TreeViewItem ItemsSource="{Binding Items}"/>
</TreeView>
两次:
"Item1"
有没有办法通过视图(XAML)标记获得所需的结果?否则,我应该更改我的视图模型,以便- Item1
- Item2
+ Group
- Item1
只会添加到Item
中,而不会添加到“根”集合中(但这是我目前要避免的)
答案 0 :(得分:0)
您可以在ViewModel中为所有项目定义两个集合,为树子定义一个集合,这似乎很简单。
class ViewModel
{
public ObservableCollection<Base> AllItems { get; set; }
public ObservableCollection<Base> RootLevelItems { get; set; }
}
如果您只有两个级别(例如没有嵌套组),则可以将ListView与GroupStyle一起使用。
答案 1 :(得分:0)
假设您有一些关于哪个项属于某个组的指示,对于此示例,我在组和项类中添加了一个Guid。
你可以通过两种方式解决这个问题:
1)创建一个复合包装类。 并创建一个Wrapper类的ItemsSource。如果有一个项目不属于某个组,则子项将保持为空。
public class Wrapper<T> where T : Base
{
public List<T> Children { get; set; }
}
public class Base
{
public string Name { get; set; }
}
public class Item : Base
{
public Guid GroupId { get; set; }
}
public class Group : Base
{
public Guid ID { get; set; }
public List<Item> GroupItems { get; private set; }
}
您的第二个选择是使用CollectionView,并过滤掉属于某个组的项目。
private ICollectionView _baseView;
public ICollectionView BaseView
{
get
{
if (_baseView == null)
{
_baseView = new ListCollectionView((IList) items);
_baseView.Filter = o => o is Group || o is Item && (o as Item).GroupId != Guid.Empty;
}
return _baseView;
}
}
答案 2 :(得分:0)
回应你的评论:
顺便说一句,集合中没有重复项,正如您在我的代码中看到的那样 - 它只是显示项目两次的视图。
你说你的代码没有重复,但显然有:
private void FillUp()
{
Item item1 = new Item { Name = "Item1" };
Item item2 = new Item { Name = "Item2" };
Group group = new Group { Name = "Group" };
group.GroupItems.Add(item1); // Adding item1 into collection in Group
this.Items.Add(item1); // Adding item1 into collection again
this.Items.Add(item2);
this.Items.Add(group);
}
因此,正如我所说,这是预期的行为,TreeView
只显示你告诉它的内容。因此,要删除重复的项目,只需将其添加到您的集合中即可:
private void FillUp()
{
Item item1 = new Item { Name = "Item1" };
Item item2 = new Item { Name = "Item2" };
Group group = new Group { Name = "Group" };
group.GroupItems.Add(item1); // Adding item1 into collection in Group
// this.Items.Add(item1); // Don't add item1 into collection again
this.Items.Add(item2);
this.Items.Add(group);
}