将列表框中的某些项绑定到combox itemsource

时间:2010-08-20 22:50:07

标签: wpf data-binding

我有一个包含许多项目的列表框,我在C#WPF中有一个组合框。

我想将组合框的itemsource绑定到列表框的项目源但是我想过滤掉一些项目(它是一个xml数据源,我希望按项目元素的某个元素的内容进行过滤) 。 示例项目:

    <Item>
<itemtype>A</itemtype>
<itemname>Name</itemname>
</item>

    <Item>
<itemtype>B</itemtype>
<itemname>Name</itemname>
</item>

我想在将项目添加到列表框时手动将项目添加到组合框中,但是当在列表框中更改项目时,项目的“名称”值不会更新。

这样做的好方法是什么?假设我只想用itemtype B显示所有项目名称。可以在wpf绑定中完成,还是必须在后面执行一些代码?

2 个答案:

答案 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。