我有一个包含许多项目的列表框,我在C#WPF中有一个组合框。
我想将组合框的itemsource绑定到列表框的项目源但是我想过滤掉一些项目(它是一个xml数据源,我希望按项目元素的某个元素的内容进行过滤) 。 示例项目:
<Item>
<itemtype>A</itemtype>
<itemname>Name</itemname>
</item>
<Item>
<itemtype>B</itemtype>
<itemname>Name</itemname>
</item>
我想在将项目添加到列表框时手动将项目添加到组合框中,但是当在列表框中更改项目时,项目的“名称”值不会更新。
这样做的好方法是什么?假设我只想用itemtype B显示所有项目名称。可以在wpf绑定中完成,还是必须在后面执行一些代码?
答案 0 :(得分:2)
在这种情况下,绑定的问题是它只设置一次。所以如果你绑定它,源是同步的。您可以使用转换器进行绑定,从而过滤您不想绑定的项目。另一种方法是使用WPF精彩的CollectionViewSource。
您可以在任何类型的ItemsSource上向GroupViewSource添加分组/排序和过滤器。例如,使用ListCollectionView。
ListCollectionView view =
(ListCollectionView)CollectionViewSource.GetDefaultView(yourEnumerableSource);
答案 1 :(得分:2)
它是对数据源的引用,例如如果使用MVC模式,则在viewmodel中的集合。令人惊奇的是,它的使用非常简单。视图已更新,并具有自己的刷新处理功能。我会做一个小例子:
在WPF中:
<ListBox ItemsSource={Binding Path=MySource} ItemTemplate="{StaticResource myItemTemplate}" />
代码逻辑:
public class Item
{
public string Name { get; set; }
public string Type { get; set; }
}
public class MyViewModel
{
public ObservableCollection<Item> MySource { get; set; }
public MyViewModel()
{
this.MySource = new ObservableCollection<Item>();
this.MySource.Add(new Item() { Name = "Item4", Type = "C" });
this.MySource.Add(new Item() { Name = "Item1", Type = "A" });
this.MySource.Add(new Item() { Name = "Item2", Type = "B" });
this.MySource.Add(new Item() { Name = "Item3", Type = "A" });
// get the viewsource
ListCollectionView view = (ListCollectionView)CollectionViewSource
.GetDefaultView(this.MySource);
// first of all sort by type ascending, and then by name descending
view.SortDescriptions.Add(new SortDescription("Type", ListSortDirection.Ascending));
view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Descending));
// now i like to group the items by type
view.GroupDescriptions.Add(new PropertyGroupDescription("Type"));
// and finally i want to filter all items, which are of type C
// this is done with a Predicate<object>. True means, the item will
// be shown, false means not
view.Filter = (item) =>
{
Item i = item as Item;
if (i.Type != "C")
return true;
else
return false;
};
// if you need a refreshment of the view, because of some items were not updated
view.Refresh();
// if you want to edit a single item or more items and dont want to refresh,
// until all your edits are done you can use the Edit pattern of the view
Item itemToEdit = this.MySource.First();
view.EditItem(itemToEdit);
itemToEdit.Name = "Wonderfull item";
view.CommitEdit();
// of course Refresh/Edit only makes sense in methods/callbacks/setters not
// in this constructor
}
}
有趣的是,这种模式直接影响了gui中的列表框。如果添加分组/排序,这将影响列表框的显示行为,即使itemssource仅绑定到viewmodel。