BindingList с моим классом, заполняющим ComboBox, используя его свойство?

У меня есть BindingList с моим классом, где я хотел бы заполнить ComboBox, используя его свойство, поэтому, когда мой список изменится, ComboBox также изменится.

public class UserAccess
{
    public override string ToString()
    {
        return Access;
    }
    public int AccessId { get; set; }
    public string Access { get; set; }
    public List<string> Command = new List<string>();

    public bool HasCommand(string cmd)
    {
        return this.Command.Any(x => x == cmd);
    }
}

public BindingList<UserAccess> accessList = new BindingList<UserAccess>();

При загрузке формы я назначаю его ComboBox:

myComboBox.DataSource = accessList;

Я хочу заполнить поле Access или AccessId в качестве значения и Access в качестве печатного имени.

Проблема в том, что он напечатает только последний элемент списка в поле со списком, что я делаю неправильно?


person Guapo    schedule 28.05.2011    source источник


Ответы (1)


Используйте DisplayMember, чтобы указать, какое поле использовать для отображения в ComboBox.
Сделайте accessList readonly, чтобы гарантировать, что вы никогда не создадите новый экземпляр списка. Если вы не сделаете это readonly, это может привести к тонкой ошибке, если вы не переназначите DataSource всякий раз, когда вы повторно создаете accessList.

private readonly BindingList<UserAccess> accessList = new BindingList<UserAccess>();

public Form1()
{
    InitializeComponent();

    comboBox1.ValueMember = "AccessId";
    comboBox1.DisplayMember = "Access";
    comboBox1.DataSource = accessList;
}

private void button1_Click(object sender, EventArgs e)
{
    accessList.Add(new UserAccess { AccessId = 1, Access = "Test1" });
    accessList.Add(new UserAccess { AccessId = 2, Access = "Test2" });
}

Если вам нужно иметь возможность изменять свойства элементов в accessList (например, accessList[0].Access = "Test3") и видеть изменения, отраженные в пользовательском интерфейсе, вам необходимо реализовать INotifyPropertyChanged.

Например:

public class UserAccess : INotifyPropertyChanged
{
    public int AccessId { get; set; }

    private string access;

    public string Access
    {
        get
        {
            return access;
        }

        set
        {
            access = value;
            RaisePropertyChanged("Access");
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        var temp = PropertyChanged;
        if (temp != null)
            temp(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
person Alex Aza    schedule 28.05.2011
comment
спасибо, это работает как шарм, не знал о проблеме с использованием только для чтения, что было полезно знать. Можно ли также создать первую запись в поле со списком по умолчанию, назначенную на -1 или 0, не добавляя ее в список? - person Guapo; 29.05.2011
comment
Если вы используете DataSource, вам необходимо сохранить значение по умолчанию -1 в качестве дополнительного элемента в вашем списке. - person Alex Aza; 29.05.2011
comment
поэтому мне все еще нужно добавить его в элементы списка. Я не могу как-то добавить его непосредственно в список перед источником данных? Например, я хотел бы сделать первый элемент элементом с именем Select:, который нельзя выбрать, чтобы сообщить человеку, что он должен выбрать доступ, чтобы он не просто создал пользователя с доступом по умолчанию. - person Guapo; 29.05.2011
comment
Это именно то, что вы должны сделать. Добавьте строку типа accessList.Add(new UserAccess { AccessId = -1, Access = "Empty" }); в качестве одной из первых строк в вашем конструкторе. Трудно предложить самый простой способ сделать это, так как вы не показываете код, который заполняет accessList. ` - person Alex Aza; 29.05.2011
comment
когда я загружаю свое приложение, оно получает JSON из моего API, и этот JSON десериализуется в список, создавая его. Поэтому я думаю, что просто добавлю в начало списка JSON, который вытягивается из базы данных, доступ -1 Select. - person Guapo; 29.05.2011