【问题标题】:binding certain items from listbox to combox itemsource将某些项目从列表框绑定到组合框项目源
【发布时间】:2010-08-20 22:50:07
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: wpf data-binding


    【解决方案1】:

    它是对数据源的引用,例如如果您使用 MVC 模式,则添加到视图模型中的集合。令人惊奇的是,它的使用非常简单。视图已更新,并具有自己的刷新处理。我举个小例子:

    在 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。

    【讨论】:

    • 感谢您的详细解释。那么如何将我当前的数据源设置为 observablecollection?因此,根据您的解释,我过滤了该集合。我是在代码中还是在 xaml 中将集合绑定到我的组合框?
    【解决方案2】:

    在这种情况下,Binding 的问题在于它只设置了一次。所以如果你绑定它,源是同步的。您可以使用转换器进行绑定,它会过滤您不喜欢绑定的项目。另一种方法是使用 WPF 出色的 CollectionViewSource。

    您可以将分组/排序和过滤器添加到任何类型的 ItemsSource 上的 CollectionViewSource。以 ListCollectionView 为例。

    ListCollectionView view = 
       (ListCollectionView)CollectionViewSource.GetDefaultView(yourEnumerableSource);
    

    【讨论】:

    • 'yourEnumerableSource' 是对列表框还是对数据源的引用?当对数据源进行更改时,视图会更新吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 2014-06-09
    • 2011-11-17
    • 2011-03-23
    • 2011-05-28
    • 1970-01-01
    相关资源
    最近更新 更多