1

標準のリストボックスを使用して、それをオブジェクトのセットにバインドし、バインドされたアイテムのコレクションを更新して、選択したものを含めたいと思います。

だから私は次のようなものを持っています:

    _pContext = new BindingSource();
_pContext.DataSource = _gpContext;
_pContext.DataMember = "ParentEntities";
_AllChildrenListBox.DataSource = _container.ChildEntities;
_AllChildrenListBox.DataBindings.Add("MySelectedItems", _pContext, "ChildEntities", false);

_allChildrenListBoxはリストボックスです。ListBoxから継承する新しいリストボックスタイプを作成したので、代替のSelectedItemsプロパティを作成して、アイテムを設定/設定解除するロジックをカプセル化できます。

つまり、一言で言えば、質問は次のとおりです。上記では、ChildEntitiesは「ChildEntity」オブジェクトのコレクションです。リストボックスには、考えられるすべてのChildEntityオブジェクトが含まれており、ChildEntitiesの要素を選択し、選択が変更されたときに更新する必要があります。

4

1 に答える 1

0

これを回避する方法を見つけました。現時点では少し醜いですが、動作します。後で改良できます。

したがって、最初のビットはバインディング自体でした。

_AllChildrenListBox.DataBindings.Add("SelectedItems2", _pContext, "ChildEntities2", true);

ここで重要なのは、フォーマット パラメータを true に設定することのようです。

次に、SelectedItems2 に汚い仕事をする何かが必要でした。これは混乱しますが、機能します。完全なクラスは次のとおりです。

    public class MyListBox : ListBox
{
    private IEnumerable<object> _original;

    public IEnumerable<object> SelectedItems2
    {
        get
        {
            return UpdateSet();
        }
        set
        {
            SelectItems(value);
        }
    }

    private IEnumerable<object> UpdateSet()
    {
        var listSource = _original as IListSource;
        IList list = null;
        if (listSource != null)
        {
            list = listSource.GetList();
        }
        var iList = _original as IList;
        if (list == null && iList != null)
        {
            list = iList;
        }
        if (list == null)
        {
            return _original;
        }

        foreach (var item in SelectedItems)
        {
            if (!list.Contains(item))
            {
                list.Add(item);
            }
        }
        foreach (var item in _original.ToList())
        {
            if (!SelectedItems.Contains(item))
            {
                list.Remove(item);
            }
        }

        return _original;

    }

    private void SelectItems(IEnumerable<object> items)
    {
        _original = items;
        var hashset = new HashSet<object>();
        foreach (var item in items)
        {
            hashset.Add(item);
        }
        for(var i=0;i<Items.Count;i++)
        {
            SetSelected(i, hashset.Contains(Items[i]));
        }
    }
}

基本的に、私はすべてのルールを破っており、IEnumerable がよりおいしいリスト ベースのインターフェイスを隠していると仮定しています。

最後に、私は EF (Entity Framework) を使用しており、コレクション プロパティのセッターを呼び出すことができないため、現在のエンティティは次のようになっています。これは最初の作業にすぎないと言いました。

    public partial class ParentEntity
{
    public IEnumerable<object> ChildEntities2
    {
        get
        {
            return new List<object>(ChildEntities);
        }
        set
        {
            if (value == null)
            {
                return;
            }
            foreach (var item in ChildEntities.ToList().Where(item => !value.Contains(item)))
            {
                ChildEntities.Remove(item);
            }

            foreach (var item in value)
            {
                var cItem = item as ChildEntity;
                if (cItem != null)
                {
                    if (!ChildEntities.Contains(item as ChildEntity))
                    {
                        ChildEntities.Add(item as ChildEntity);
                    }
                }
            }                
        }
    }
}
于 2012-12-12T15:54:59.990 に答える