I have a class ParamObj (which implements INotifyPropertyChanged) which contains a property DefaultValues of type ObservableCollection<Param>. My Param class (which also implements INotifyPropertyChanged) contains two properties: Name and IsSelected.
On button click I am populating a StackPanel with TextBlock and ComboBox controls. Each Param in the collection DefaultValues is an option in the ComboBox, where the Name property represents the text of that option and IsSelected is a boolean value representing if that option is the one currently selected in the ComboBox.
Param class below:
public class Param : INotifyPropertyChanged
{
public enum ParamType
{
Unknown=-1,
Text=0,
Option=1,
Multi=2
}
private string pName = string.Empty;
private bool pSelected = false;
private ParamType pType = ParamType.Unknown;
public string Name { get { return pName; } set { pName = value; OnPropertyChanged("Name"); } }
public bool IsSelected { get { return pSelected; } set { pSelected = value; OnPropertyChanged("IsSelected"); } }
public ParamType Type { get { return pType; } }
public Param(string name, bool selected)
{
this.pName = name;
this.pSelected = selected;
this.pType = ParamType.Option;
}
//INotifyPropertyChanged base
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
}
}
ParamObj class below:
public class ParamObj : INotifyPropertyChanged
{
//ui type mapping
public enum UITypeEnum
{
Textbox = 0,
ComboBox = 1,
CheckableComboBox = 2
}
private string name = string.Empty;
private UITypeEnum uiType = UITypeEnum.Textbox;
private ObservableCollection<Param> defaultVals = new ObservableCollection<Param>();
private string propDescription = string.Empty;
public string Name { get { return name; } set { name = value; OnPropertyChanged("Name"); } }
public UITypeEnum UIType { get { return uiType; } set { uiType = value; OnPropertyChanged("UIType"); } }
public ObservableCollection<Param> DefaultValues { get { return defaultVals; } }
public string Desc { get { return propDescription; } set { propDescription = value; } }
//Initialization
public ParamObj()
{
}
public void ClearDefaultValues()
{
this.defaultVals.Clear();
OnPropertyChanged("DefaultValues");
}
public void AddDefaultValue(Param objAdded)
{
this.defaultVals.Add(objAdded);
}
public void AddDefaultValueRange(Param[] objsToAdd)
{
foreach (Param o in objsToAdd)
{
this.defaultVals.Add(o);
}
}
//INotifyPropertyChanged base
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
}
}
Code below is called in the button click event. po represents a ParamObj instance.
case ParamObj.UITypeEnum.ComboBox:
cb = new ComboBox();
cb.Height = 26;
cb.Width = 210;
cb.Margin = new Thickness(2);
cb.VerticalContentAlignment = System.Windows.VerticalAlignment.Center;
cb.DataContext = po.DefaultValues;
//binding
cb.ItemsSource = po.DefaultValues;
cb.DisplayMemberPath = "Name";
cb.SelectedValuePath = "IsSelected";
cb.SelectedValue = true;
cb.SelectionChanged += ParamComboBox_SelectionChanged;
break;
Here’s the problem. ComboBox items are populated successfully and the option (Param object) that has an IsSelected value of true is selected. What I thought would happen is that when I changed the selected option in the ComboBox the IsSelected property’s value (boolean) of the Param object would be toggled from false to true. This didn’t happen. So I added the cb.SelectionChanged += ParamComboBox_SelectionChanged event to the ComboBox.
private void ParamComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!(sender is ComboBox)) return;
ComboBox cb = sender as ComboBox;
Param cp = (Param)cb.SelectedItem;
if (cp.IsSelected == false)
{
foreach (Param p in cb.ItemsSource)
{
p.IsSelected = false;
}
cp.IsSelected = true;
}
}
Through debugging I do see that the IsSelected properties are correctly updated, but the values in my po object are not updated with the new values.
Any suggestions are greatly appreciated. I’ve tried my darndest to figure this out but I’m stuck.
Brian
This is one of the problems that appear to be very simple, but seems like there is no easy or direct way to bind the ComboBoxItem IsSelected to a given property. One possible solution that comes to my mind could be:
First, Add a Style of type ComboBoxItem to your ComboBox and add a Trigger to that style. This trigger will fire when you have selected a ComboBoxItem and will call the helper class in step 2.
If you want to do this same thing programmatically, then you go:
Then, Create a IsSelectedBehaviorClass to handle your IsSelected Behavior. This static class will receive the currently selected ComboBoxItem and set the Param.IsSelected property accordingly. Something like this:
Finally you can test your solution on the SelectionChanged EventHandler