Reputation: 83264
In my application, I will need to update a certain image when the selection of my combobox
changes. Currently I do this by capturing the SelectedIndexChanged
event and update the image there.
I have been trying another approach to do it, namely, using Binding
in order to simplify my code, but it doesn't work.
Because the binding of ComboBox.SelectedItem
to a certain property only applies after the ComboBox
loses focus or when another control gains focus-- not when or before the SelectedIndexChanged
event is fired.
How to get the binding to apply immediately when the SelectedItem
or the SelectedIndex
is changed?
This is my code:
public partial class Form1 : Form
{
private readonly Person person;
public Form1()
{
InitializeComponent();
person = new Person()
{
Name = "joe",
Race = Race.Indian
};
textBox1.DataBindings.Clear();
textBox1.DataBindings.Add(nameof(textBox1.Text), person, nameof(person.Name));
comboBox1.DataSource = Enum.GetValues(typeof(Race));
comboBox1.DataBindings.Clear();
comboBox1.DataBindings.Add(nameof(comboBox1.SelectedItem), person, nameof(person.Race));
comboBox1.SelectedIndexChanged += ComboBox1_SelectedIndexChanged;
}
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//when selected index is changed, the data is lagging behind the selected item.
//eg: SelectedItem is already Chinese, but person.Race is still Indian
MessageBox.Show($"data {person.Race}, selected item {comboBox1.SelectedItem}");
}
private int count = 0;
private void button1_Click(object sender, EventArgs e)
{
person.Race =(Race)(((int)person.Race + 1) % Enum.GetValues(typeof(Race)).Length);
person.Name = person.Name + $"{count++}";
}
}
public enum Race
{
Indian,
Chinese,
Causacian,
Arabian,
Jewish,
SouthINdian,
}
public class Person: INotifyPropertyChanged
{
private Race _race;
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
public Race Race
{
get
{
return _race;
}
set
{
_race = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs (nameof(Race)));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
Upvotes: 3
Views: 881
Reputation: 125247
To solve the problem, you can bind to SelectedValue
property:
comboBox1.DataSource = Enum.GetValues(typeof(Race)).Cast<Race>()
.Select(x => new { Value = x, Display = x.ToString() })
.ToList();
comboBox1.DisplayMember = "Display";
comboBox1.ValueMember = "Value";
comboBox1.DataBindings.Add(nameof(comboBox1.SelectedValue), person, nameof(person.Race),
true, DataSourceUpdateMode.OnPropertyChanged);
Upvotes: 4