問題描述
如何同時綁定到 ComboBox 中的兩個不同的依賴屬性? (How do I bind to two different dependency properties in a ComboBox at the same time?)
I have a ComboBox that has I've created a binding to a List of items, but when I try to bind the selected item property, it doesn't do anything. It used to work when I bound only the SelectedValueProperty. The class already implements INotifyPropertyChanged.
public void ComboBoxBinding() {
Dictionary<long, string> myDictionary = new Dictionary<long, string>
Control control = new ComboBox();
comboBoxControl = (ComboBox)control;
comboBoxControl.SetBinding(ComboBox.ItemsSourceProperty, createFieldBinding("myDictionary"));
comboBoxControl.DisplayMemberPath = "Value";
comboBoxControl.SelectedValuePath = "Key";
binding = createFieldBinding(fieldProperty);
control.SetBinding(ComboBox.SelectedItemProperty, createFieldBinding("fieldProperty")); // <-- This doesn't seem to bind.
}
private Binding createFieldBinding(string propertyName) {
Binding binding = new Binding(fieldName);
binding.Source = this.DataContext;
binding.UpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged;
return binding;
}
I set up a function that would change the dictionary variable, and the values in the ComboBox change, but I cannot get the SelectedValueProperty to change. How do I do that?
Edit: If I create a dictionary and set ItemsSource manually, it works, but when I set the binding, it doesn't.
Dictionary<long, string> myDictionary = new Dictionary<long, string>();
myDictionary.Add(1, "test1");
myDictionary.Add(2, "test2");
myDictionary.Add(3, "test3");
myDictionary.Add(4, "test4");
myDictionary.Add(5, "test5");
myDictionary.Add(6, "test6");
myDictionary.Add(7, "test7");
myDictionary.Add(8, "test8");
myDictionary.Add(9, "test9");
myDictionary.Add(10, "test10");
comboBoxControl.ItemsSource = myDictionary; //<-- This works, but if I use Binding instead of manually setting the ItemsSource, it does not work
參考解法
方法 1:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public long SelectedValue { get { return selectedValue; } set { selectedValue = value; Notify("SelectedValue"); } }
private long selectedValue;
private Dictionary<long, string> myDictionary;
public Dictionary<long, string> MyDictionary { get { return myDictionary; } set { myDictionary = value; Notify("MyDictionary"); } }
public MainWindow()
{
InitializeComponent();
DataContext = this;
ComboBoxBinding();
MyDictionary = new Dictionary<long, string>() { { 1, "abc" }, { 2, "xyz" }, { 3, "pqr" } };
SelectedValue = 2;
}
public void ComboBoxBinding()
{
Control control = new ComboBox();
comboBoxControl = (ComboBox)control;
comboBoxControl.SetBinding(ComboBox.ItemsSourceProperty, createFieldBinding("MyDictionary"));
comboBoxControl.DisplayMemberPath = "Value";
comboBoxControl.SelectedValuePath = "Key";
comboBoxControl.SetBinding(ComboBox.SelectedValueProperty, createFieldBinding("SelectedValue"));
}
private Binding createFieldBinding(string fieldName)
{
Binding binding = new Binding(fieldName);
binding.Source = this.DataContext;
binding.UpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged;
return binding;
}
private void Notify(string propName)
{
if(PropertyChanged!=null)
PropertyChanged(this,new PropertyChangedEventArgs(propName));
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
You can bind Properties only.Fields can not be Binded.I hope this will help.
方法 2:
The reason it wasn't binding was because I was defining the Dictionary in the ViewModel directly instead of creating a temporary Dictionary and setting it to the Property that implements INotifyPropertyChanged, which stops the Binding from recognizing the link between the member and the property a field was bound to.
Instead of doing:
private Dictionary<long, string> _myList = new Dictionary<long, string>();
public Dictionary<long, string> MyList {
get { return _myList; }
set { _myList = value;
PropertyChanged("MyList"); }
}
public void Init() {
_myList.Add(1, "One");
}
I had to set a temporary Dictionary and apply that to the Property.
private Dictionary<long, string> _myList = new Dictionary<long, string>();
public Dictionary<long, string> MyList {
get { return _myList; }
set { _myList = value;
PropertyChanged("MyList"); }
}
public void Init() {
Dictionary<long, string> tempList = new Dictionary<long, string>();
tempList.Add(1, "One");
MyList = tempList;
}
(by Bob.、yo chauhan、Bob.)