Pregunta

Suponga que está haciendo algo como lo siguiente

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

Ahora tenemos 2 cuadros combinados vinculados a esa matriz y todo funciona bien.Pero cuando cambia el valor de un cuadro combinado, cambia AMBOS cuadros combinados al que acaba de seleccionar.

Ahora, sé que las matrices siempre se pasan por referencia (lo aprendí cuando aprendí C: D), pero ¿por qué los cuadros combinados cambiarían juntos?No creo que el control del cuadro combinado esté modificando la colección en absoluto.

Como solución alternativa, ¿no lograría esto la funcionalidad esperada o deseada?

ComboBox box = new ComboBox();
box.DataSource = myitems.ToArray();
¿Fue útil?

Solución

Esto tiene que ver con cómo se configuran los enlaces de datos en el marco dotnet, especialmente el BindingContext.En un nivel alto, significa que si no ha especificado lo contrario, cada formulario y todos los controles del formulario comparten lo mismo. BindingContext.Cuando estás configurando el DataSource propiedad la ComboBox utilizará el BindingContext conseguir un ConcurrenyMangager eso envuelve la lista.El ConcurrenyManager realiza un seguimiento de cosas tales como la posición seleccionada actualmente en la lista.

Cuando configuras el DataSource del segundo ComboBox usará lo mismo BindingContext (los formularios) que darán como resultado una referencia al mismo ConcurrencyManager como se utiliza arriba para configurar los enlaces de datos.

Para obtener una explicación más detallada consulte Contexto vinculante.

Otros consejos

Una mejor solución (dependiendo del tamaño de la fuente de datos) es declarar dos BindingSource Los objetos (nuevos a partir de 2.00) vinculan la colección a aquellos y luego los vinculan a los cuadros combinados.

Adjunto un ejemplo 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);
        }
    }
}

Si quiere confundirse aún más, intente declarar siempre enlaces en el constructor.Eso puede resultar en algunos en realidad errores curiosos, por eso siempre me vinculo en el evento Load.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top