1

デリゲートの結果を返す 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) に基づいているコレクションを組み込むクラスをどのように構築しますか?

前もって感謝します。

4

1 に答える 1

0

これが私がこれまでに思いついたものです。まだ多くのテストを行っていませんが、これまでのところかなり見栄えがします。

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
}

を使用してComboBoxにバインドできますItemsSource="{Binding Path=myCollection, Mode=TwoWay}"DyamicCollection myCollectionViewModel /データコンテキストでプロパティとして設定している場合)。

これはすべて、クエリを設定することで機能します。私の場合は、リストを返すLINQtoXMLクエリを指定します。コレクションはこれを更新し、バインドされたComboBoxはこの更新を反映します。

これを批評してください。私は何かを持っているとかなり確信しています、あるいはこれを行うためのより良い方法があるかもしれません。私はフィードバックを受け付けており、この回答が進化するにつれて更新します。

于 2012-08-17T14:02:49.857 に答える