dados WinForms ComboBox pegadinha ligao

votos
44

Suponha que você está fazendo algo como o seguinte

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

Portanto, agora temos 2 caixas de combinação vinculados a essa matriz, e tudo funciona bem. Mas quando você alterar o valor de uma caixa de combinação, ele muda as duas caixas de combinação para o que você acabou de selecionar.

Agora, eu sei que Arrays são sempre passados ​​por referência (aprendi que quando eu aprendi C: D), mas porque na terra que as caixas de combinação mudar juntos? Eu não acredito que o controle de caixa de combinação é modificar a coleção em tudo.

Como um trabalho em torno, não isso iria atingir a funcionalidade que é esperado / desejado

ComboBox box = new ComboBox();
box.DataSource = myitems.ToArray();
Publicado 02/08/2008 em 17:09
fonte usuário
Em outras línguas...                            


3 respostas

votos
37

Isso tem a ver com a forma como ligações de dados são criados no quadro dotnet, especialmente o BindingContext. Em um nível elevado, isso significa que se você não tiver especificado de outra forma cada formulário e todos os controles do share forma o mesmo BindingContext. Quando você está definindo a DataSourcepropriedade ComboBoxusará o BindingContextde obter uma ConcurrenyMangagerque envolve a lista. O ConcurrenyManagerguarda informação sobre coisas como a posição atual selecionado na lista.

Ao definir o DataSourceda segunda ComboBoxvai utilizar os mesmos BindingContext(as formas) que vai produzir uma referência para o mesmo ConcurrencyManagercomo acima utilizado para configurar as ligações de dados.

Para obter uma explicação mais detalhada ver BindingContext .

Respondeu 02/08/2008 em 18:18
fonte usuário

votos
20

Uma solução alternativa melhor (dependendo do tamanho da fonte de dados) é declarar dois BindingSourceobjectos (novos como de 2,00) se ligam a recolha para aqueles e, em seguida, se ligam aqueles para as caixas de combinação.

Incluo um exemplo completo.

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);
        }
    }
}

Se você quer confundir-se ainda mais, em seguida, tentar sempre declarar ligações no construtor. Isso pode resultar em alguns realmente erros curiosos, daí eu sempre ligar no evento Load.

Respondeu 21/08/2008 em 15:48
fonte usuário

votos
2

Este poderia ser apenas um erro, mas no código que você forneceu só referência primeira caixa de combinação ao definir a fonte de dados:

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

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

A fonte de dados para box2não está definido.

Respondeu 21/08/2008 em 18:12
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more