Is it possible to bind a List<T> to a listbox control? I see examples that seem to do this by simply assigning the listbox's datasource property to the List<T>. However, I don't seem to have the option of a datasource property.
Here is what I'd like to do. I've got a List<UserListItems>. A UserListItem consists of the fields Name, Phone, Email, Level. On the UI I have a listbox control which will list all users by name. When a user is selected from the listbox, 4 text boxes are populated. These textboxes are associated with the fields in UserListItem.
Ideally these would all be bound such that the user can modify a text box field and the associated List<T> item is updated.
EDIT:
Adding the specific list that I want to bind.
//EXAMPLE BIND IN WPF FORM
ListUsers.DisplayMemberPath = "Name";
ListUsers.ListUsers.DataContext = device.UsersTable;
//OBJECT CREATION FROM WITHIN DEVICE CLASS
UsersTable = new DeviceDataTable<UserListItem>();
//INTERFACE AND EXTENDED LIST
interface IDeviceTableItem
{
byte[] ToByteArray();
byte UID
{
set;
get;
}
int RowSize
{
set;
get;
}
}
class DeviceDataTable<T> : IEnumerable<T> where T : IDeviceTableItem
{
private List<T> table = new List<T>();
public T this[int pos]
{
get
{
return table[pos];
}
set
{
table[pos] = value;
}
}
public void AddRow(T r)
{
table.Add(r);
this.UpdateID();
}
public void RemoveRow(Int32 i)
{
table.RemoveAt(i);
this.UpdateID();
}
private void UpdateID()
{
byte i = 0;
foreach (T t in table)
{
t.UID = i++;
}
}
private byte[] ToByteArray()
{
byte[] tableArray=new byte[table.Count];
return tableArray;
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return table.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return table.GetEnumerator();
}
}
//HERE IS ONE POSSIBLE DEVICE TABLE
class UserListItem : IDeviceTableItem
{
public const int FIELD_SIZE_UID = 1;
public const int FIELD_SIZE_NAME = 32;
public const int FIELD_SIZE_CELL = 16;
public const int FIELD_SIZE_EMAIL = 64;
public const int FIELD_SIZE_LEVEL = 1;
private const int FIELD_OFFSET_UID = 0;
private const int FIELD_OFFSET_NAME = FIELD_OFFSET_UID + FIELD_SIZE_UID;
private const int FIELD_OFFSET_CELL = FIELD_OFFSET_NAME + FIELD_SIZE_NAME;
private const int FIELD_OFFSET_EMAIL = FIELD_OFFSET_CELL + FIELD_SIZE_CELL;
private const int FIELD_OFFSET_LEVEL = FIELD_OFFSET_EMAIL + FIELD_SIZE_EMAIL;
private int ROW_SIZE = FIELD_SIZE_UID + FIELD_SIZE_NAME + FIELD_SIZE_CELL + FIELD_SIZE_EMAIL + FIELD_SIZE_LEVEL;
public enum AccessLevels : byte
{
Admin = 1,
Ordinary = 2
}
private byte uid;
public string Name;
public string CellPhone;
public string Email;
public AccessLevels Level;
public byte UID
{
set
{
this.uid = value;
}
get
{
return this.uid;
}
}
public int RowSize
{
set
{
}
get
{
return this.ROW_SIZE;
}
}
public UserListItem(string name, string cellphone, string email, AccessLevels level)
{
this.Name = name;
this.CellPhone = cellphone;
this.Email = email;
this.Level = level;
}
public byte[] ToByteArray()
{
byte[] rowArray= new byte[ROW_SIZE];
//Construct byte array representing table row
rowArray[FIELD_OFFSET_UID] = UID;
System.Text.ASCIIEncoding encoding = new ASCIIEncoding();
encoding.GetBytes(this.Name.PadRight(FIELD_SIZE_NAME).Substring(0, FIELD_SIZE_NAME - 1)).CopyTo(rowArray, FIELD_OFFSET_NAME);
encoding.GetBytes(this.CellPhone.PadRight(FIELD_SIZE_CELL).Substring(0, FIELD_SIZE_CELL - 1)).CopyTo(rowArray, FIELD_OFFSET_CELL);
encoding.GetBytes(this.Email.PadRight(FIELD_SIZE_EMAIL).Substring(0, FIELD_SIZE_EMAIL - 1)).CopyTo(rowArray, FIELD_OFFSET_EMAIL);
rowArray[FIELD_OFFSET_LEVEL] = (byte)this.Level;
return rowArray;
}
}

1 answers
What I'd do is something like this:
EDIT - WPF version of the above
answered 2 years ago by:
17279
499
I don't seem to have a DataSource property, or a DisplayMember property. I have DataContext and DisplayMemberPath. Thoughts?
499
It seems that the properties are different because I am using WPF?? Not sure about that statement but that's what I gather. Anyways, after much digging I found that I need to set ItemsSource=users as well as DataContext=users. I've done this but I still have issues. Suggestions?
17279
I've editied my answer to include the equivalent code in WPF.
499
Thanks Vulpes! I am almost there I believe. I was able to take your example and get it to work but I am having trouble binding a specific list. I've edited my original post so that it formats nicely. Any thoughts as to why a simple list would work and this will not?
499
FYI, when I bind the data (ex: Device.UsersTable ) it doesn't generate an exception or anything... simply no data shows in the listbox.
17279
The problem is that Name in the UserListItem class needs to a public property rather than a field. Also the ListUsers.ItemsSource property needs to be set to device.UsersTable. I wouldn't bother setting the DataContext property.
499
Almost there :). I changed the Name field to a property (public string Name{set;get;}). Data is now bound to the listbox but, the Name does not show. The list items in the box are simply blank. Now if I use UID as the DisplayMemberPath instead of Name, the number appears in the listbox. They are both properties of the same list. The property Name is definitely returning a string representing the users name. Thoughts?
499
I got it to work... I was doing something silly. Thanks again vulpes!
510
eeboy, why not mark the question as answered?