2009-03-23 18 views
9

Estoy escribiendo una aplicación de Windows y el uso de un control de cuadro de lista. Estoy desarrollando con Visual Studio C# 2008 Express Edition.algún que otro problema con ListBox.DataSource

Tengo un objeto de datos que se ve algo como esto

public class RootObject 
{ 
    public List<SubObject> MySubObjects{ get; set;} 
} 

Tengo un ListBox en mi forma, y ​​también un "MyRootObject" propiedad que, obviamente, tiene un RootObject. Cuando se inicializa el control, me puse:

_listBox.DataSource = MyRootObject.MySubObjects; 

Ahora, cuando se carga el formulario, que depurar y ver que el origen de datos está siendo ajustado correctamente. Pero no se muestra nada. He reemplazado el método ToString() de SubObject y ni siquiera se está llamando. Intenté configurar _listBox.DisplayMember en una propiedad de SubObject solo para ver si había algún problema allí, pero aún nada. Traté de llamar _listBox.Update() y _listBox.Refresh() después de establecer el origen de datos, pero todavía no hay amor. DataSource tiene todos los datos ... solo se niega a mostrarlo.

Así, mientras que la depuración, me preguntaba WTF y yo decidimos a hacer lo suficientemente

_listBox.DataSource = new List<SubObject>{ new SubObject(), new SubObject() }; 

Claro, esto funcionó, y veo dos cosas que figuran en mi cuadro de lista.

Así pues, realmente curioso, yo decidimos probar la copia de la lista de objetos y poner que en el cuadro de lista, así:

_listBox.DataSource = MyRootObject.MySubObjects.ToArray(); 

Esto funciona! Y es una solución a mi problema por ahora ... pero muy molesto. ¿Alguien sabe por qué tengo que copiar básicamente la lista de objetos como este para conseguir que funcione, en lugar de sólo la creación de la _listBox.DataSource = MyRootObject.MySubObjects; ? Una vez más, DataSource tiene todos los datos correctos de cualquier manera después de configurarlo ... es justo cuando se copian los datos, en realidad se muestra, y cuando no lo está, no se muestra.

Respuesta

1

En la parte superior de mi cabeza, esto se debe a que la propiedad ListBox.DataSource debe contener algo que implemente la interfaz IList. Su List<SubObject> genérica no implementa IList; implementa IList<T> (en el espacio de nombres System.Collections.Generic). Array objetos, por otra parte, no heredan de IList, por lo que la entrega de los datos a través de ese tipo de obras objeto.

Usted podría intentar tirar un Enumerator (que también implementa IList) fuera de su objeto List<SubObject> y enchufe que en. Si funciona, entonces el problema que he descrito es su problema. Si no es así, entonces estoy hablando sin mi sombrero.

Si este es realmente el problema, me sorprende que empujar en un objeto no admitido no arroje una excepción.

+0

tengo este mismo problema, y ​​esta página dice que la lista sí implementa IList, así como IList : https://social.msdn.microsoft.com/Forums/vstudio/en- US/a58e4f37-4abd-4eff-820e-33d09a7a432d/net-classes-that-implement-ilist? Forum = netfxbcl –

0

Yo creo que hay que llamar al método de enlace después de asignar a la fuente de datos de cuadro de lista algo así como _listBox.DataSource.bind() y que tendrá su cuadro de lista desapareció

0

usted podría tratar de usar un BindingSource (http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.aspx)

entre el Listbox y su colección.Bindingsources maneja un montón de cosas y también incluye las propiedades Suspend/ResumeBinding que pueden ser útiles al actualizar la lista

También puede probar wpf ya que su enlace de datos es muy superior al de winforms :) pero quizás eso no sea posible en su caso

0

Creo que necesita llamar a _listbox.DataBind(); después de asignar el origen de datos. Sin embargo, nunca antes había usado una propiedad como fuente de datos, solo he usado métodos. ¿Has intentado cambiar tu propiedad a un método para ver si ese es el problema?

+2

Podría estar equivocado, pero creo que solo es aplicable en ASP.NET. Creo que el OP probablemente esté usando Winforms. –

+0

Lo siento, no me di cuenta de eso. Probablemente tengas razón. Gracias por la aclaración. :-) –

1

hasta ahora, que yo sepa, cada vez que desee establecer una colección a un

[ComboBox,ListBox].DataSource 

usted tiene que fijar el DisplayMember y ValueMember. DisplayMember y ValueMember se rellenan con el nombre de propiedad de la clase en la colección que está asignada al listbox/combobox. Ex.

//Populate the data 
RootObject root = new RootObject(); 
root.MySubObjects.Add(new SubObject("1", "data 1")); 
root.MySubObjects.Add(new SubObject("2", "data 2")); 

//Assign data to the data source 
_listBox.DisplayMember = "DisplayProperty"; 
_listBox.ValueMember = "ValueProperty"; 
_listBox.DataSource = root.MySubObjects; 

root.MySubObjects devuelve Lista de subobjeto y subobjeto tiene que tener propiedades denominadas DisplayProperty y ValueProperty, ex.

public class RootObject 
{ 
    public List<SubObject> MySubObjects { get; set; } 
} 

public class SubObject 
{ 
    public string ValueProperty { get; set; } 
    public string DisplayProperty { get; set; } 
} 
+1

Configuración de DisplayMember y ValueMember es habitual, pero opcional; si no configura DisplayMember, el control llama a ToString() en el objeto; y si no establece ValueMember, el control devuelve el objeto completo para el valor. – Bevan

0

Usted podría intentar

_listBox.DataSource = new BindingList<SubObject> (MyRootObject.MySubObjects); 

lugar. BindingList implementa algunas interfaces más que List, que son esenciales para DataBinding.

0

Tengo una regla especial para problemas como este que siempre trato de recordar antes de perder todo un día martillándolo (¡créanme, he pasado muchos días martillando!). La regla es: cuando el comportamiento del sistema es realmente extraño, la causa subyacente debe ser muy estúpida. Como programadores inteligentes, tenemos la tendencia de buscar causas esotéricas o errores en el código de la estructura para explicar nuestros problemas. A veces la respuesta es que estábamos apurados y cometimos un error por descuido que aún no hemos detectado.

Para citar a Sherlock Holmes, "cuando eliminas lo imposible, entonces lo que queda, por improbable que sea, debe ser la verdad". En este caso, la verdad inverosímil es que la propiedad MySubObjects del objeto MyRoot es nula.

5
((CurrencyManager)_listBox.BindingContext[_listBox.DataSource]).Refresh(); 

Sux0r Lo sé, pero esto funciona. (que se encuentra originalmente respuesta here)

Cuestiones relacionadas