【问题标题】:Collection/CollectionView based on Linq query in SilverlightSilverlight 中基于 Linq 查询的 Collection/CollectionView
【发布时间】:2012-08-15 20:25:01
【问题描述】:

我正在研究绑定到返回委托结果的 ObservableCollection 属性的概念证明。委托也为其设置了一个属性,这样我就可以更改使用的表达式,它会触发集合的 OnPropertyChanged。这允许我将 ComboBox 绑定到 Collection,并且在更改表达式/查询时,ComboBox 中的可用选项也会发生变化。

代码:

public delegate List<string> Del();

private Del _query;
public Del Query
{
    get
    {
        return _query;
    }
    set
    {
        _query= value;
        OnPropertyChanged("BindList");
    }
}

private ObservableCollection<string> bindList;
public ObservableCollection<string> BindList
{
    get
    {
        var results = Query();
        bindList = new ObservableCollection<string>(results);
        return bindList;
    }
    set
    {//I believe I need this setter for the extra functionality provided by ObservableCollections over Lists
        if(bindList != value) {
            bindList = value;
            OnPropertyChanged("BindList");
        }
    }
}

既然这行得通,我想用它创建一个易于绑定的类。我正在寻求有关如何执行此操作的指导。我曾考虑过将 ObservableCollection 子类化一些,但在如何设置 Items 时遇到了问题。我还考虑了一个使用 IEnumerable 和 ICollectionView 等接口的自定义类(以及通知接口)。

因此,总而言之,您将如何构建一个类来合并一个集合,该集合的成员基于关于子类化/接口的委托查询(具体为 LINQ)?

提前致谢。

【问题讨论】:

  • ICollectionView 看起来像是答案的一部分。它具有 SourceCollection 的只读属性,我认为它应该只在我的类中引用一个私有列表?除非我也从某个集合类继承,否则当我尝试绑定到我的类时,我不必绑定到 myCollection.SourceCollection 或绑定到 myCollection 就足够了(myCollection 是我的自定义类的类型)。我宁愿不必做点语法,因为我会有很多这样的东西,它只会变得杂乱无章。

标签: c# linq silverlight delegates observablecollection


【解决方案1】:

这是我到目前为止的想法。尚未进行大量测试,但目前看起来还不错。

public class DynamicCollection<T> : IEnumerable, INotifyCollectionChanged
{
    public ICollectionView Collection { get; private set; }

    public delegate List<T> Del();

    private Del query;
    public Del Query
    {
        get
        {
            return query;
        }
        set
        {
            if (query != value)
            {
                query = value;//set the new query
                T currentItem = (T)Collection.CurrentItem;//save current item
                Collection = new PagedCollectionView(Query());//recreate collection with new query
                Collection.MoveCurrentTo(currentItem);//move current to the previous current (if it doesn't exist, nothing is selected)
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));//Notify colleciton has changed.
            }
        }
    }

    public DynamicCollection()
    {
        Collection = new PagedCollectionView(new List<T>());//empty collection
    }

    public DynamicCollection(IEnumerable<T>collection)
    {
        Collection = new PagedCollectionView(collection);
    }

    public DynamicCollection(Del delegateQuery)
    {
        Query = delegateQuery;
    }

    #region IEnumerable Members
    public IEnumerator GetEnumerator()
    {
        return Collection.GetEnumerator();
    }
    #endregion IEnumerable Members

    #region INotifyCollectionChanged Members
    public event NotifyCollectionChangedEventHandler CollectionChanged;
    protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        NotifyCollectionChangedEventHandler handler = CollectionChanged;
        if (handler != null)
        {
            CollectionChanged(this, e);
        }
    }
    #endregion INotifyCollectionChanged Members
}

它可以使用 ItemsSource="{Binding Path=myCollection, Mode=TwoWay}" 绑定到 ComboBox 中(假设您已将 DyamicCollection myCollection 设置为 ViewModel/数据上下文中的属性)。

这一切都通过设置查询来工作,在我的例子中,我给出了一个返回列表的 LINQ to XML 查询。 Collection 对此进行更新,绑定的 ComboBox 反映了此更新。

请随时批评。我相当肯定我已经完成了一些事情,或者也许有更好的方法来做到这一点。我愿意接受反馈,并将随着它的发展更新这个答案。

【讨论】:

    猜你喜欢
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多