Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > ListBox.DisplayMember getting reset to empty string
 

ListBox.DisplayMember getting reset to empty string

I have a ListBox which I set the DataSource again and again, but in certain situations, DisplayMember will be reset to "" (String.Empty).

in design or initially:

myListBox.DisplayMember = "Caption";

then:

myListBox.DataSource = GetSomeList();

will reset the DisplayMember to "" on occasion.

This only happens if ListBox's handle hasn't been created yet and the current data source's count is 1 greater than the previous.

I created a test form and put the listbox inside a tabcontrol on page 2 (so that it's hidden) and a button to assign an increasing number of items to the datasource. When I increment the number by more than 1, it does not happen but when I increase it by 1, it happens.

If you enable thefirst time exception for IndexOutOfRangeException, you'll see where it's happening.
Not sure why or how i'm going to work around this though yet.
doughboy  Wednesday, July 08, 2009 10:08 PM
Hi doughboy,

Does GetSomeList method sometime return null value?

The DataSource property of ListBox is inherited from ListControl. If you look into the source code of ListControl with Reflector, you can see DisplayMember will be reset. Here is the code from reflector.

[AttributeProvider(typeof(IListSource)), DefaultValue((string) null), SRDescription("ListControlDataSourceDescr"), RefreshProperties(RefreshProperties.Repaint), SRCategory("CatData")]
public object DataSource
{
get
{
return this.dataSource;
}
set
{
if (((value != null) && !(value is IList)) && !(value is IListSource))
{
throw new ArgumentException(SR.GetString("BadDataSourceForComplexBinding"));
}
if (this.dataSource != value)
{
try
{
this.SetDataConnection(value, this.displayMember, false);
}
catch
{
this.DisplayMember = "";
}
if (value == null)
{
this.DisplayMember = "";
}
}
}
}
if the value is null, the DisplayMember will be set to "", if error occur in SetDataConnection method, DisplayMember will be set to "" too.

Sincerely,
Kira Qian
Please mark the replies as answers if they help and unmark if they don't.
Kira Qian  Friday, July 10, 2009 6:50 AM
Thanks Kira,

I did find a workaround and I'll post it here for anyone who runs into the same issue.
By the way, my datasource is never null.

As I stated in my original post, it seems to have something to do with the ListBox's handle being created or not. I followed into the source via Reflector and learned that the call goes into SetDataConnection and eventually comes to a location where the execution path splits depending on whether native handle is created or not. If there is a native handle then it does not reset DisplayMember; otherwise it does.

So as a workaround, I call CreateControl() on the ListBox in my UI code and make sure the handle is created. I have to do that in my case because the ListBox is on a tab which is not initially visible.

It seems a little odd that I have to do this but it seems to work just fine.
doughboy  Thursday, August 20, 2009 2:47 PM

Hi doughboy,
I also had same issue with listbox, thats also because of handle was not created.
That is solved by following code,
Intptr handle = listBox1.Handle;

NareshG  Thursday, August 20, 2009 3:00 PM
Right. The first time Handle is called, if the native handle isn't created, it calls CreateHandle to create it, which CreateControl also ends up calling.
doughboy  Thursday, August 20, 2009 3:10 PM
HiKira Qian

I read your answer, and I think that is a good answer for doughboy, so I have another doubt,

Why my listbox show the name of the class instead of the corresponding value as DisplayMember?

For example...
I have a ListBox, and show the displaymember correctly, so, after of couple of process, I hava to do the DataSource, null, and after read your answer, I set DisplayMember to my property, for example "Name", before set the DataSource, then
Why not do the listbox show me the correspondig value?

I hope u can answer me, I excuse my english, I am new in this (I speak spanish :P)

Thanks

Garnachas  Wednesday, September 16, 2009 8:22 PM
Hi Garnachas,

Normally we set DataSource before setting DisplayMember. What's the type of your list items? Did you expose a public property for the field you want to show in the listbox?

Sincerely,
Kira Qian
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework!
Kira Qian  Thursday, September 17, 2009 6:52 AM
Ok Kira Qian

Well, I had the next experience, in DataGridView, i set the datasource before the display member, but when I set the display member, the grid took so time like I set the DataSource... so I did the test, and I set first the displaymember and after the datasource, and the time load decrease to the half, then I think with the ListBox was the same

Well return with your question I use a generic class, here mi code of mi class

using System;
using System.Collections.Generic;
using System.Text;

namespace Entidades.Administracion
{
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public class OrganizacionBE
{
private int _intIDOrganizacion;
private string _strNombre;
private string _strDireccion;
private string _strDescripcion;
private bool _bolEstatus;

#region Metodos Get y Set
public bool Estatus
{
get { return _bolEstatus; }
set { _bolEstatus = value; }
}

public string Descripcion
{
get { return _strDescripcion; }
set { _strDescripcion = value; }
}

public string Direccion
{
get { return _strDireccion; }
set { _strDireccion = value; }
}

public string Nombre
{
get { return _strNombre; }
set { _strNombre = value; }
}

public int IDOrganizacion
{
get { return _intIDOrganizacion; }
set { _intIDOrganizacion = value; }
}
#endregion

public OrganizacionBE(int pIntIDOrganizacion, string pStrNombre, string pStrDireccion, string pStrDescripcion) {
_intIDOrganizacion = pIntIDOrganizacion;
_strNombre = pStrNombre;
_strDireccion = pStrDireccion;
_strDescripcion = pStrDescripcion;
}


}
}


And I fill my ListBox with a Collection inherit CollectionBase, here my code

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Entidades.Administracion
{
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public class OrganizacionBECollection : CollectionBase
{
private static string _strValueField = "IDOrganizacion";
private static string _strTextField = "Nombre";

public static string ValueField
{
get { return OrganizacionBECollection._strValueField; }
}

public static string TextField
{
get { return OrganizacionBECollection._strTextField; }
}


public int Add(OrganizacionBE value)
{
return (List.Add(value));
}
public void Add(int idx, OrganizacionBE value)
{
List.Insert(idx, value);
}

public OrganizacionBE this[int index]
{
get { return ((OrganizacionBE)List[index]); }
set { List[index] = value; }
}

public void Remove(OrganizacionBE pEntidad)
{
List.Remove(pEntidad);
}

public OrganizacionBE Find(OrganizacionBE pEntidad)
{
return this[List.IndexOf(pEntidad)];
}

public OrganizacionBE Find(int pId)
{
IEnumerator IE = List.GetEnumerator();
while (IE.MoveNext()) //Recorre la Coleccion con el Enumerador....
{
if (((OrganizacionBE)IE.Current).IDOrganizacion == pId)
return (OrganizacionBE)IE.Current;
}
return null;
}

public void Remove(int intIDOrganizacion)
{
OrganizacionBE obj = this.Find(intIDOrganizacion);
if (obj != null)
this.Remove(obj);
}
}
}

Well, my code to fill the ListBox...

this.lisOrganizaciones.ValueMember = OrganizacionBECollection.ValueField;
this.lisOrganizaciones.DisplayMember = OrganizacionBECollection.TextField;
this.lisOrganizaciones.DataSource = _colOrganizaciones;

And so my problem is here... I try this...


this.lisOrganizaciones.DataSource = null;
this.lisOrganizaciones.DisplayMember = OrganizacionBECollection.TextField;
this.lisOrganizaciones.DataSource = _colOrganizaciones;

And here, I should do that you say..., Could you show me the reflection of DisplayMember?, or Could you say me how can i do it?


Thanks a lot

Garnachas  Thursday, September 17, 2009 2:09 PM

You can use google to search for other answers

Custom Search

More Threads

• How do I total columns?
• Transforming data values?
• Datatable sorting?
• Unable to Insert,Update,Delete Data in VS2005 Proffessional Edition
• How to print table correct DataGrid? Help please for newbie!
• HasChanges always return true, when check for unsaved data
• Need help selecting from a databound listbox.
• Copying items from one listview to another
• How to position a small form inside a bigger one when clicking on acertain button without cutting the smaller form
• Data Connections Wizard Not Working Ole DB Visual Basic 2008 Express