56

次のようなことをしているとします

List<string> myitems = new List<string>
{
    "Item 1",
    "Item 2",
    "Item 3"
};

ComboBox box = new ComboBox();
box.DataSource = myitems;

ComboBox box2 = new ComboBox();
box2.DataSource = myitems

これで、2 つのコンボ ボックスがその配列にバインドされ、すべて正常に動作しました。ただし、1 つのコンボ ボックスの値を変更すると、両方のコンボ ボックスが選択したものに変更されます。

今、私は配列が常に参照によって渡されることを知っています (私が C :D を学んだときにそれを学びました)、一体なぜコンボ ボックスが一緒に変更されるのでしょうか? コンボ ボックス コントロールがコレクションをまったく変更しているとは思えません。

回避策として、これは期待/望ましい機能を達成しないでください

ComboBox box = new ComboBox();
box.DataSource = myitems.ToArray();
4

2 に答える 2

39

これは、dotnet フレームワーク、特にBindingContext. 大まかに言えば、特に指定しない限り、各フォームとフォームのすべてのコントロールが同じ を共有することを意味しますBindingContextDataSourceプロパティを設定する場合、ComboBoxは を使用してリストをラップするBindingContextを取得します。ConcurrenyMangagerConcurrenyManager、リスト内で現在選択されている位置などを追跡します。

DataSource秒のを設定するComboBoxと、同じBindingContext(フォーム) がConcurrencyManager使用され、データ バインディングの設定に使用されたものと同じものへの参照が生成されます。

より詳細な説明については、BindingContextを参照してください。

于 2008-08-02T17:18:12.680 に答える
22

より良い回避策 (データソースのサイズによって異なります) は、2 つのオブジェクト (2.00 以降の新機能) を宣言しBindingSourceてコレクションをそれらにバインドし、それらをコンボボックスにバインドすることです。

完全な例を同封します。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private BindingSource source1 = new BindingSource();
        private BindingSource source2 = new BindingSource();

        public Form1()
        {
            InitializeComponent();
            Load += new EventHandler(Form1Load);
        }

        void Form1Load(object sender, EventArgs e)
        {
            List<string> myitems = new List<string>
            {
                "Item 1",
                "Item 2",
                "Item 3"
            };

            ComboBox box = new ComboBox();
            box.Bounds = new Rectangle(10, 10, 100, 50);
            source1.DataSource = myitems;
            box.DataSource = source1;

            ComboBox box2 = new ComboBox();
            box2.Bounds = new Rectangle(10, 80, 100, 50);
            source2.DataSource = myitems;
            box2.DataSource = source2;

            Controls.Add(box);
            Controls.Add(box2);
        }
    }
}

さらに混乱させたい場合は、コンストラクターで常にバインディングを宣言してみてください。これにより、非常に奇妙なバグが発生する可能性があるため、常にLoad イベントにバインドします。

于 2008-08-21T14:48:34.283 に答える