#c# #.net #winforms #generics #tostring
#c# #.net #winforms #обобщения #tostring
Вопрос:
Кто-нибудь может это объяснить:
public class Test : List<int>
{
public override string ToString()
{
return "My ToString";
}
}
Если я создам этот экземпляр и добавлю его в ListBox
элемент управления в Windows Form
, он отобразит «Collection», а не «My toString».
Test test = new Test();
listBox1.Items.Add(test);
Я думал, что add to Items
просто вызовет мой класс ToString()
. Конечно, следующее работает так, как ожидалось
MessageBox.Show(test.ToString());
Ответ №1:
Чтобы это сработало, вы должны отключить форматирование:
listBox1.FormattingEnabled = false;
Похоже, что если форматирование включено, оно выполняет некоторые волшебные трюки, и результат не всегда такой, каким он должен быть…
Комментарии:
1. Я не могу поверить, что listboxes работают таким образом. Мне потребовалась вечность, чтобы даже определить правильную комбинацию слов в Google, чтобы найти этот вопрос для решения проблемы. Ужасно. Хотя ответ хороший.
Ответ №2:
Установите DisplayMember в ListBox в свойство тестового типа.
listBox1.DisplayMember = "Name";
Чтобы решить вашу проблему, добавьте свойство с именем «Name» в Type и в getter вызова toString.
public class Test : List<Int32>
{
public String Name { get { return this.ToString(); } }
public override string ToString()
{
return "Test";
}
}
Комментарии:
1. Да, я это тоже знаю … вопрос в том, почему Listbox.items.add не вызывает мой переопределенный toString()?
Ответ №3:
Разве это не обязательно должно быть так:
listBox1.Items.Add(test.ToString());
Я полагаю, вы хотите, чтобы ваш listbox содержал строковый тип?
Не уверен, что это правильно, хотя я не тестировал это.
Комментарии:
1. Конечно, это работает, но Add () получает объект, а не просто вызывает Object. toString() который является виртуальным? Если я изменю свой класс на наследование от Object, это сработает…
Ответ №4:
Элементы в ListBox представляют собой набор объектов, а не строк.
Смотрите MSDN: ListBox.ObjectCollection.Добавить метод
Следовательно, вам нужно либо добавить экземпляр в виде строки (например: listBox1.Items.Add(test.ToString());
) во внешнем интерфейсе, либо во внутреннем интерфейсе, когда вы просматриваете listbox, вы должны вызвать toString (например: listBox1.Items[0].ToString();
).
Комментарии:
1. Нет — если вы были правы, почему добавление int в listbox работает? Он вызывает виртуальный метод toString() в Object. Если я изменяю свой класс для наследования от Object, он также работает…
Ответ №5:
Я тоже сталкивался с этим (и еще одно спасибо, Манджи!). У меня было что-то вроде этого:
public override string ToString()
{
return MessageText;
}
Где MessageText был текстовым полем среди нескольких других, и оно работало нормально. Позже я изменил это на это
public override string ToString()
{
return string.Concat("[", MessageTime.ToString("yyyy-MM-dd HH:mm:ss.fffff"), "] ", MessageText);
}
И это все равно вернет только содержимое поля MessageText (время вытягивания волос). Интересно было то, что контекстное меню в ListBox, которое я настроил для копирования выбранных элементов в буфер обмена, использовало полное переопределение toString.
Лично я думаю, что свойство FormattingEnabled по умолчанию должно иметь значение false, а не true, я обнаружил, что IDE (или настройки управления) часто сбивают меня с толку, пытаясь быть умным.
/// Редактировать: опечатка (помните, что нельзя печатать с помощью elbows!