ListBox.DisplayMember = [String] Могу ли я как-то обойти это, кроме строки в .NET? - PullRequest
3 голосов
/ 15 июня 2009

Вопрос задается относительно Объектного источника данных. Поэтому учтите, что у меня есть класс

public class Customer{

    public String name;
    public int age;

    public Customer(String name, int age) {
         this.name = name;
         this.age = age;
    }
}

И у меня есть привязка списка к списку этих объектов. Поэтому я говорю

listBox.DisplayMember = "name";

Но мой вопрос заключается в том, что, когда я изменяю название моего класса Customer на

public String fullName;

DisplayMember по-прежнему остается на «имя». Это не удастся. Так что это снижает мою способность к рефакторингу доменных объектов. Есть ли способ для этого?

Ответы [ 7 ]

5 голосов
/ 17 февраля 2010

Это более сексуальное и гибкое решение

Отрывок ...

Короче говоря, вместо писание:

textBoxCustomerName.DataBindings.Add("Text", bindingSource, "CustomerName");

я предлагаю написать что-нибудь как:

dataSource.CreateBinding(textBoxCustomerName, ctl => ctl.Text, data => data.Name);

Таким образом, ваш код все еще будет работать без проблем при рефакторинге ваши сущности (скажем, если вы переименовать собственность клиента Name до CompanyName).

Довольно мило, а?

Также здесь есть некоторые решения Как сделать тип привязки данных безопасным и поддержать рефакторинг

1 голос
/ 15 июня 2009

Если вы оставите DisplyMember пустым, то ListBox будет использовать ToString () по умолчанию. Когда вы переопределите эту функцию в своем классе, в списке отобразится соответствующее значение. Затем, если вы измените имя поля, ваша сборка прервется в функции ToString ().

1 голос
/ 15 июня 2009

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

string DisplayMember
{
    get { return 'name'; }
}

и при рефакторинге вашего объекта вам нужно только изменить возвращаемую строку на новое имя свойства, сделав его изменением в одном месте, а не в нескольких.

Это не здорово, но работает лучше, чем жесткое кодирование в приложении!

НТН

ONESHOT

0 голосов
/ 20 ноября 2018

Поскольку C # 6.0 , вы можете использовать оператор nameof , который возвращает имя переменной / члена / типа в виде строки.

listBox.DisplayMember = nameof(Customer.Name);

(при условии, что есть класс с именем Customer со свойством Name)

Из официального справочника языков :

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

(акцент мой)

0 голосов
/ 15 июня 2009

Единственный реальный способ «обойти» эту «проблему» - добавить новое открытое свойство ReadOnly. Назовите это свойство «ListDisplay» или что-то подобное. Затем вы можете изменить реализацию без какого-либо влияния на пользовательский интерфейс.

Это не идеальная ситуация, но она работает.

0 голосов
/ 15 июня 2009

ReSharper может сделать это для вас ... попробуйте получить его - действительно отличный программный продукт. Возможно, CodeRush тоже сможет это сделать. Но я не уверен.

0 голосов
/ 15 июня 2009

Вот почему вы должны использовать свойства, а не открытые поля для представления данных из ваших классов. Вы можете легче реорганизовать внутреннюю работу, не ломая слишком много. Хотя, конечно, будут случаи, когда вам придется что-то сломать.

...