Привязка данных WinForms ComboBox

Предположим, вы делаете что-то вроде следующего

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 поля со списком, связанные с этим массивом, и все работает отлично. Но когда вы меняете значение одного поля со списком, оно заменяет оба поля со списком, которые вы только что выбрали.

Теперь я знаю, что массивы всегда передаются по ссылке (узнал, что когда я выучил C: D), но с какой стати комбо-боксы менялись вместе? Я не верю, что элемент управления combo box вообще изменяет коллекцию.

В качестве обходного пути, не достигните ли вы ожидаемой / желаемой функциональности

ComboBox box = new ComboBox();
box.DataSource = myitems.ToArray();
2.08.2008 16:09:56
2 ОТВЕТА
РЕШЕНИЕ

Это связано с тем, как привязки данных устанавливаются в среде dotnet, особенно с BindingContext. На высоком уровне это означает, что, если вы не указали иное, каждая форма и все элементы управления формы совместно используют одно и то же BindingContext. Когда вы устанавливаете DataSourceсвойство, оно ComboBoxбудет использовать, BindingContextчтобы получить ConcurrenyMangagerобтекание списка. ConcurrenyManagerОтслеживает такие вещи , как текущая выбранной позиции в списке.

Когда вы устанавливаете DataSourceвторой, ComboBoxон будет использовать те же BindingContext(формы), что даст ссылку на то же, ConcurrencyManagerчто и выше, использованный для настройки привязок данных.

Чтобы получить более подробное объяснение, смотрите BindingContext .

38
24.12.2019 07:28:40
Похоже, что нужно приложить немало усилий, чтобы сделать контроль привязки данных полностью интуитивно понятным.
Belmiris 1.06.2015 15:13:45
Это объясняет, почему возникает проблема - но не предлагает никакого решения?
UuDdLrLrSs 24.04.2019 14:51:43

Лучший обходной путь (в зависимости от размера источника данных) состоит в том, чтобы объявить два BindingSourceобъекта (новые, начиная с версии 2.00), связать коллекцию с этими объектами и затем связать их с выпадающими списками.

Я прилагаю полный пример.

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.

21
14.10.2012 12:35:23
Спасибо за указание, что привязка в конструкторе приводит к некоторым действительно любопытным ошибкам. У меня была похожая проблема, и я переместил свой код в событие Load, и оно показало связанные данные.
bunggo 8.10.2013 19:47:27
Я нашел некоторые из самых странных незарегистрированных ошибок с этим. В худшем случае, когда выпадающий список отказывался сосредоточиться на каком-либо другом элементе управления: D
Quibblesome 9.10.2013 10:07:58