我的模型类如下所示:
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集合现在包含两个类型为Item的对象和一个类型为Group的对象,该对象具有对一个Item对象的“父-子”引用。
我想要实现的是:我想在TreeView中显示这个模型,这样属于某些Group的所有Item都应该显示为该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":
- Item1
- Item2
+ Group
- Item1是否有任何方法仅通过视图(XAML)标记获得所需的结果?否则,我应该更改我的视图模型,以便只将Item添加到Group中,而不是在“根”集合中(这是我目前试图避免的)。
发布于 2015-02-05 11:21:40
假设您对哪个项属于一个组有一些指示,那么在这个示例中,iv'e在group和Item类中添加了一个Guid。
你可以从两方面着手:
1)创建复合包装器类。并创建包装类的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;
}
}发布于 2015-02-05 10:56:22
您可以在ViewModel中定义两个集合--一个用于所有项,一个用于树,这似乎很简单。
class ViewModel
{
public ObservableCollection<Base> AllItems { get; set; }
public ObservableCollection<Base> RootLevelItems { get; set; }
}如果您只有两个级别(例如,没有嵌套组),则可以将ListView与GroupStyle结合使用。
发布于 2015-02-05 12:03:54
在回应你的评论时:
顺便说一句,集合中没有重复项,正如您在我的代码中所看到的那样--它只是显示项目两次的视图。
您说过您的代码中没有重复项,但显然有:
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);
}https://stackoverflow.com/questions/28340249
复制相似问题