Поле со списком C# переопределило ToString

У меня возникли некоторые проблемы при работе с ComboBox.

Элемент отображения для моего поля со списком не заполняется переопределенным методом ToString класса MAP.

Вот мой код:

Form1.cs:

private void Form1_Load(object sender, EventArgs e) {  
    ...  
    ...      
    MAPList MAP = new MAPList();  
    comboBox1.DataSource = MAP.All;  
    comboBox1.ValueMember = "Code";  
    ...  
    ...  
}

MAPList.cs:

public class MAPList {  
    public readonly List<MAP> All;

    public MAPList() {
        All = new List<MAP>();

        var MapData = // Getting map data

        foreach(MAP m in MapData) {
            All.Add(new Map(m.Name, m.Code));
        }
    }
}

MAP.cs:

public class MAP {
    public readonly string Name;

    private string code;
    public string Code { get { return code; } }

    public RadioCode(string Name, string Code) {
        this.Name = Name;
        this.code = Code;
    }

    public override string ToString() {
        return String.Format("{0}: {1}", Name, Code);
    }
}

person Moon    schedule 08.09.2010    source источник
comment
Каковы отношения? Я не вижу, чтобы вы где-нибудь называли карту объектов   -  person vodkhang    schedule 08.09.2010
comment
Так что же отображается вместо этого? Просто МАП?   -  person Dan Tao    schedule 08.09.2010
comment
Вы устанавливаете ValueMember в код свойства. Нигде не будет вызвано ваше переопределение .ToString. Вместо переопределения ToString просто используйте этот код, представленный как свойство экземпляра, и привяжите его.   -  person RPM1984    schedule 08.09.2010
comment
@Dan Tao: Нет. Ценность кода   -  person Moon    schedule 08.09.2010
comment
@vodkhang: не переопределяет ли ToString управление тем, что пользователь видит в поле со списком ??   -  person Moon    schedule 08.09.2010
comment
@Руби - точно. Вы привязываетесь к свойству Code, поэтому он отображает код. Привязать к свойству, которое возвращает String.Format({0}: {1}, Name, Code); Вы привязываетесь к строковому значению, почему скомпилированный вызов .ToString для строки? Ответ @Dan Tao правильный.   -  person RPM1984    schedule 08.09.2010


Ответы (4)


ToString не будет вызываться, если вы установите ValueMember. Если вы не установите ValueMember, он будет работать, как и ожидалось, но тогда, конечно, Code не будет использоваться в качестве выбранного значения ComboBox.

В качестве альтернативы, если вы хотите использовать ValueMember, вы также можете установить DisplayMember. Вы можете создать свойство на вашем MAP, которое будет использоваться для отображения, т.е.:

public class MAP
{
    public readonly string Name;

    private string code;

    public string Code { get { return code; } }
    public string Display { get { return ToString(); } }

    public MAP(string Name, string Code)
    {
        this.Name = Name;
        this.code = Code;
    }

    public override string ToString()
    {
        return String.Format("{0}: {1}", Name, Code);
    }
}

В форме вы можете установить DisplayMember:

MAPList MAP = new MAPList();
comboBox1.DataSource = MAP.All;
comboBox1.ValueMember = "Code";
comboBox1.DisplayMember = "Display";
person Jakob Christensen    schedule 08.09.2010

Это связано с тем, что вы установили для свойства ValueMember значение «Код», поэтому значения в поле со списком являются не вашими объектами Map, а скорее строками, соответствующими их свойствам Code.

Если вы удалите эту строку:

comboBox1.ValueMember = "Code";

... он будет работать так, как вы ожидаете.

Если вы хотите, чтобы ComboBox отображал свои элементы в соответствии с методом ToString вашего типа Map, тогда Ответ Джейкоба правильный: создайте свойство для вашего типа Map, которое предоставляет строку, отформатированную именно так, как вы хотите, и установите для свойства DisplayMember ComboBox имя this< /em> свойство.

person Dan Tao    schedule 08.09.2010
comment
Я согласен, и это было именно так, как я реализовал это раньше. Но мои требования вынуждают меня извлекать значение кода, когда я делаю comboBox1.SelectedValue, а не форматированную строку. - person Moon; 08.09.2010
comment
@Ruby: см. ответ Якоба; Я думаю, что это именно то решение, которое вы ищете. - person Dan Tao; 08.09.2010

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

person Vinay B R    schedule 08.09.2010

Я знаю, что это старый пост, но если кто-то хочет использовать ToString() без создания свойства для простого вызова ToString(), вам придется явно установить значение DisplayMember в пустую строку, например:

Form1.cs:

private void Form1_Load(object sender, EventArgs e) {  
    ...  
    ...      
    MAPList MAP = new MAPList();  
    comboBox1.DataSource = MAP.All;  
    comboBox1.ValueMember = "Code"; 
    comboBox1.DisplayMember = "";  // Explicitly set it to an empty String
    ...  
    ...  
}
person Alisson    schedule 26.01.2015
comment
К вашему сведению, вам нужно установить .ValueMember перед .DisplayMember. Я делал это неправильно, и проблема все еще была. Как только я переключился, это было исправлено! - person Jimenemex; 06.06.2019