Обновить BackColor для ListBox

#c# #winforms #binding

#c# #winforms #привязка

Вопрос:

Мне нужно обновить BackColor моего ListBox, выбрав цвет из выпадающего списка и нажав на кнопку.Вот мой код

       public Data _current;
    public Data Current
    {
        get
        { return _current; }
        set
        {
            _current = value;

            if (PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("Current"));
            }
        }
    }
    public Form1()
    {
        InitializeComponent();
        Items = new ObservableCollection<Data>();
        for (int i = 0; i < names.Count; i  )
        {
            Items.Add(new Data() {Name=names[i].ToString().TrimStart(new char[] { '[', 'C', 'o', 'l', 'o', 'r', ' ', ']' }).TrimEnd(new char[] { ']' }), color = names[i] });
        }

        comboBox1.DataSource = Items;
        comboBox1.DisplayMember ="Name";
        Current = Items.First();

    }
    public List<Color> names = new List<Color>() { Color.Red,Color.Yellow,Color.Green,Color.Blue };

    public event PropertyChangedEventHandler PropertyChanged;
    private void button1_Click(object sender, EventArgs e)
    {
        Current = comboBox1.SelectedItem as Data;
        listBox1.DataBindings.Add("BackColor", Current, "color", true, DataSourceUpdateMode.OnPropertyChanged);
    }
    private void Form1_Load(object sender, EventArgs e)
    {
    }
}
public class Data:INotifyPropertyChanged
{
    private Color _color;

    public string name { get; set; }
    public string Name
    {
        get
        { return name; }
        set
        {
            name = value;
            if (PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("Name"));
            }
        }
    }
    public Color color
    {
        get
        {
            return _color;
        }
        set
        {
            _color = value;
            if (PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("color"));
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}
  

Выскакивает исключение и говорит: «Это приводит к тому, что две привязки в коллекции привязываются к одному и тому же свойству».

Комментарии:

1. Вам не нужна привязка к данным для обновления backcolor of ListBox , если вы хотите обновить обратный цвет ListBox с помощью Click события of Button .

Ответ №1:

Для решения вашей первоначальной проблемы «Мне нужно обновить BackColor моего ListBox, выбрав цвет из выпадающего списка и нажав на кнопку», вам вообще не нужна привязка к данным. Вы можете просто сделать это с

 private void button1_Click( object sender, EventArgs e )
{
    listBox1.BackColor = (Color)comboBox1.SelectedValue;
}
  

Если вы действительно хотите сделать это с помощью привязки данных, вы можете выполнить привязку непосредственно между listbox и combobox (ок, это не требует нажатия кнопки):

 listBox1.DataBindings.Add( "BackColor", comboBox1, "SelectedValue", true, DataSourceUpdateMode.OnPropertyChanged );
  

Если вам нужна привязка данных и кнопка, вы можете привязать combobox с помощью form.Current

 comboBox1.DataBindings.Add( "SelectedItem", this, "Current", true, DataSourceUpdateMode.OnPropertyChanged );
  

и обновить backcolor при нажатии кнопки:

 private void button1_Click( object sender, EventArgs e )
{
    listBox1.BackColor = Current.Color;
}
  

Вот полный пример, включающий еще несколько улучшений:

 public class Data : INotifyPropertyChanged
{
    public string Name
    {
        get { return color.Name; }
    }

    private Color color;
    public Color Color
    {
        get { return color; }
        set
        {
            color = value;

            if( PropertyChanged != null )
                this.PropertyChanged( this, new PropertyChangedEventArgs( "Color" ) );
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

public class Form1 : Form
{
    private ComboBox comboBox1;
    private ListBox listBox1;
    private Button button1;

    public Form1()
    {
        InitializeComponent();

        List<Data> dataList = new List<Data>
        {
            new Data { Color = Color.Red },
            new Data { Color = Color.Yellow },
            new Data { Color = Color.Green },
            new Data { Color = Color.Blue },
        };

        comboBox1.DataSource = dataList;
        comboBox1.DisplayMember = "Name";
        comboBox1.ValueMember = "Color";
    }

    public Data Current
    {
        get { return comboBox1.SelectedItem as Data; }
    }

    private void button1_Click( object sender, EventArgs e )
    {
        listBox1.BackColor = Current.Color;
    }

    private void InitializeComponent()
    {
        //...
    }
}
  

Ответ №2:

Вы можете привязать любое свойство элемента управления только один раз, в противном случае вы получите ArgumentException :

Это приводит к тому, что две привязки в коллекции привязываются к одному и тому же свойству. Имя параметра: привязка

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

Чтобы решить проблему, переместите код привязки данных в событие загрузки формы.

Если по какой-либо причине вы хотите добавить привязку в событие нажатия кнопки, чтобы решить проблему, вы можете проверить, не была ли добавлена привязка, а затем добавить привязку:

 if (listBox1.DataBindings["BackColor"] == null)
    listBox1.DataBindings.Add("BackColor", Current, "color", true, 
        DataSourceUpdateMode.OnPropertyChanged);
  

Комментарии:

1. Да, я попытался, переместив код привязки данных в событие Form_Load, но то, что мне нужно написать в событии нажатия кнопки..

2. Нет проблем, вы можете проверить if (listBox1.DataBindings["BackColor] == null) , а затем добавить привязку.

3. Я пишу приведенный выше код в событии click, после чего цвет меняется только один раз, на самом деле эксперимент заключается в выборе цвета из выпадающего списка, и при нажатии на кнопку backcolor для listbox обновляется соответствующим образом.. Итак, здесь он обновляется только один раз, после чего цвет не обновляется..

4. Сообщение отвечает на ваш вопрос об исключении, которое вы получили.