2009-03-23 3 views
9

Я пишу приложение Windows и использую элемент управления Listbox. Я разрабатываю Visual Studio C# 2008 Express Edition.Нечетная проблема с ListBox.DataSource

У меня есть объект данных, который выглядит примерно так

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

У меня есть ListBox на моей форме, а также свойство «MyRootObject», который, очевидно, держит RootObject. Когда элемент управления инициализируется, я установил:

_listBox.DataSource = MyRootObject.MySubObjects; 

Теперь, когда форма загружается, отлаживать и видеть, что DataSource в настоящее время установлены правильно. Но ничего не отображается. Я переопределил метод ToString() SubObject, и он даже не вызван. Я попытался установить _listBox.DisplayMember в свойство SubObject, чтобы увидеть, есть ли там какая-то проблема, но все равно ничего. Я пробовал вызывать _listBox.Update() и _listBox.Refresh() после установки DataSource, но до сих пор не люблю. У DataSource есть все данные ... он просто отказывается отображать его.

Так во время отладки, я подумал, WTF, и я решил просто сделать достаточно

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

Конечно, это сработало, и я вижу две вещи, перечисленные в моем ListBox.

Итак, очень любопытно, я решил попробовать скопировать список объектов и положить, что в ListBox, например, так:

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

Это работает! И это обходное решение моей проблемы на данный момент ... но очень раздражает. Кто-нибудь знает, зачем мне в основном копировать список таких объектов, чтобы заставить его работать, а не просто устанавливать _listBox.DataSource = MyRootObject.MySubObjects; ? Опять же, DataSource имеет все нужные данные в любом случае после его установки ... это просто, когда это скопированные данные, они фактически отображаются, а когда нет, они не отображаются.

ответ

1

Сверху моей головы это связано с тем, что свойство ListBox.DataSource должно содержать что-то, что реализует интерфейс IList. Ваш общий List<SubObject> не реализует IList; он реализует IList<T> (в пространстве имен System.Collections.Generic). Array объекты, с другой стороны, наследуют от IList, поэтому передача данных через этот вид объектов работает.

Вы можете попробовать потянув Enumerator (который также реализует IList) из вашего List<SubObject> объекта и подключить что. Если он работает, то проблема, которую я описал, это ваша проблема. Если это не так, я говорю из своей шляпы.

Если это действительно проблема, я удивлен, что перетаскивание неподдерживаемого объекта не вызывает исключения.

+0

У меня эта же проблема, и эта страница говорит, что список ДЕЛАЕТ реализации IList, а также IList : https://social.msdn.microsoft.com/Forums/vstudio/en- US/a58e4f37-4abd-4eff-820e-33d09a7a432d/net-classes-that-implement-ilist? Forum = netfxbcl –

0

Я думаю, вы должны вызвать метод Bind после присвоения источника данных блока списка что-то вроде _listBox.DataSource.bind() и вы будете иметь ваш ListBox исчез

0

вы можете попробовать и использовать BindingSource (http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.aspx)

между списком и вашей коллекцией.Bindingsources обрабатывает кучу вещей, а также включает в себя свойства Suspend/ResumeBinding, которые могут быть полезны при обновлении списка

Вы также можете попробовать wpf, так как его привязка данных намного выше, чем у winforms :), но, возможно, это невозможно в вашем case

0

Я считаю, что вам нужно позвонить _listbox.DataBind(); после присвоения источника данных. Однако, я никогда раньше не использовал свойство как источник данных, я использовал только методы. Вы пытались изменить свою собственность на метод, чтобы узнать, есть ли проблема?

+2

Я мог ошибаться, но я считаю, что это применимо только в ASP.NET. Я думаю, что OP, вероятно, использует Winforms. –

+0

Извините, я этого не заметил. Возможно Вы правы. Спасибо за разъяснения. :-) – 2009-04-01 15:34:32

1

до сих пор, что я знаю, когда вы хотите, чтобы установить коллекцию в

[ComboBox,ListBox].DataSource 

вы должны установить DisplayMember и ValueMember. DisplayMember и ValueMember заполняются именем свойства класса в коллекции, который присваивается списку/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 возвращает Список подобъекте и подобъекте должен иметь свойства, называемые DisplayProperty и ValueProperty, напр.

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

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

Настройка DisplayMember и ValueMember является обычной, но необязательной; если вы не настроите DisplayMember, элемент управления вызывает ToString() на объекте; и если вы не установите значение ValueMember, элемент управления вернет весь объект для значения. – Bevan

0

Вы можете попробовать

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

вместо этого. BindingList реализует несколько интерфейсов, чем List, которые необходимы для DataBinding.

0

У меня есть специальное правило для таких проблем, которое я всегда стараюсь запомнить, прежде чем тратить на него целый день (поверьте мне, я провел много дней, забивая!). Правило: когда поведение системы действительно странно, основная причина должна быть очень глупой. Как интеллектуальные программисты, мы склонны искать эзотерические причины или ошибки в коде кода, чтобы объяснить наши проблемы. Иногда ответ заключается в том, что мы спешили и совершили неосторожную ошибку, которую мы еще не поймали.

Процитировать Шерлока Холмса «когда вы устранили невозможное, то все, что остается, как бы невероятно оно ни было, должно быть правдой». В этом случае невероятная правда заключается в том, что свойство MySubObjects объекта MyRoot равно null.

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

Sux0r Я знаю, но это работает. (первоначально найден ответ here)

Смежные вопросы