Переопределение toString() и добавление в ListBox C#

#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!