Mohd Anzal
Mohd Anzal

Reputation: 167

Update BackColor for ListBox

I need to update BackColor of my ListBox by selecting the color from combobox and when clicked on the button.Here is my code

      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;
}

Exception pop's out and says:"This causes two bindings in the collection to bind to the same property."

Upvotes: 0

Views: 92

Answers (2)

Kai Thoma
Kai Thoma

Reputation: 572

For solving your original problem "I need to update BackColor of my ListBox by selecting the color from combobox and when clicked on the button" you do not need databinding at all. You can just do it with

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

If you really want to do it with databinding, you can bind directly between listbox and combobox (ok, this does not involve a button click):

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

If you need databinding and buttonclick you can bind combobox with form.Current

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

and update backcolor on button click:

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

Here is the complete example incuding some more improvements:

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()
    {
        //...
    }
}

Upvotes: 2

Reza Aghaei
Reza Aghaei

Reputation: 125257

You can bind any property of a control only once, otherwise you will receive an ArgumentException:

This causes two bindings in the collection to bind to the same property. Parameter name: binding

In your code you have added data-binding in click event handler of button and each time you click the code executes.

To solve the problem, move data-binding code to Load event of form.

If for any reason you want to add binding in click event of button, to solve the problem you can check if the binding has not been added then add the binding:

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

Upvotes: 1

Related Questions