如何绑定多个 ComboBox 的 ItemsSoure 相互连接
How can I bind many ComboBox's ItemsSoure Connected to each other
我有三个组合框。三个绑定相同的 ItemsSource.
这个 ItemsSouce 类型是 Dictionary<string, Dictionary<CustomKey, CustomClass>>
自定义键
public struct CustomKey<T1,T2> // T1, T2 is string
{
public readonly T1 Symbol;
public readonly T2 Column;
public CustomKey(T1 key1, T2 key2) { Symbol = key1; Column = key2; }
}
自定义类
public class CustomClass
{
public string Value{get;set}
}
First. FirstComboBox的ItemsSoure是Dictionary.Keys
Second. 我想设置 Second ComboBox 的 Items Source 是 FirstComboBox 的 SelectedItems.
像这样 Dictionary[FirstComboBox.SelectedItem]。按键 T1
Third. ThirdComboBox 的 ItemsSource Dictionary[FirstComboBox.SelectedItem].Keys T2
最后一个。
这是我的代码...
// Source.GetNames 是 ItemsSource.Keys.ToList();
protected virtual FrameworkElement CreateAutoCompleteComboBoxControl(PropertyItem property)
{
var c = new AutoCompleteComboBox();
ContinuityBindablePropertyItem cbp = (property as ContinuityBindablePropertyItem); // cbp is First ComboBox SelectedItem Descriptor. but i don't know how to use...
if (property.DisplayName == "Sheet") // First ComboBox
{
c.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source.GetSheetNames");
}
else if (property.DisplayName == "TestName") // Second ComboBox
{
c.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source.GetSheetNames");
}
else if (property.DisplayName == "Symbol") // Third ComboBox
{
c.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source.GetSheetNames");
}
c.SetBinding(ComboBox.TextProperty, property.CreateBinding());
return c;
}
请帮助我。
我英语说得不好。希望你明白。
谢谢。
编辑
改变方法。
protected virtual FrameworkElement CreateAutoCompleteComboBoxControl(PropertyItem property)
{
StackPanel s = new StackPanel();
var c1 = new AutoCompleteComboBox { Name = "c1", DisplayMemberPath = "Key", IsEditable = property.IsEditable, ItemsSource = property.ItemsSource, VerticalContentAlignment = VerticalAlignment.Center };
var c2 = new AutoCompleteComboBox { IsEditable = property.IsEditable, ItemsSource = property.ItemsSource, VerticalContentAlignment = VerticalAlignment.Center };
var c3 = new AutoCompleteComboBox { IsEditable = property.IsEditable, ItemsSource = property.ItemsSource, VerticalContentAlignment = VerticalAlignment.Center };
c1.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source") { Source = MappingService.Instance, Mode = BindingMode.OneWay });
c2.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Values") { Source = c1.SelectedItem, Mode = BindingMode.OneWay });
c3.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("SelectedItem.Values") { ElementName = c1.Name, Mode = BindingMode.OneWay });
c1.SetBinding(ComboBox.TextProperty, property.CreateBinding());
c2.SetBinding(ComboBox.TextProperty, property.CreateBinding());
c3.SetBinding(ComboBox.TextProperty, property.CreateBinding());
s.Children.Add(c1);
s.Children.Add(c2);
s.Children.Add(c3);
return s;
}
我尝试绑定路径 'Values'、'Value'、'SelectedItem.Value'、'SelectedItem.Values、将源更改为 C1.SelectedItem 或元素名称 = c1...
但是没用
编辑
添加图像。
我对您正在尝试做的事情感到有点困惑,我想我需要更多的代码或示例来理解它。但我会尝试解决一些问题。另外,我习惯了xaml,所以你可能要补上绑定代码的空缺:
First. FirstComboBox's ItemsSoure is Dictionary.Keys
只是为了检查一下,这是有效的吗?
Second. I want to set Second ComboBox's Items Source is
FirstComboBox's SelectedItems. like this
Dictionary[FirstComboBox.SelectedItem].Keys T1
Third. ThirdComboBox's ItemsSource
Dictionary[FirstComboBox.SelectedItem].Keys T2
这两个本质上是同一个问题,你想绑定到Dictionary.Keys,但是有一个组合框显示T1,另一个显示T2?好的,与其尝试将 ComboBox 直接绑定到 Dictionary[FirstComboBox.SelectedItem].Keys T1,我建议使用以下两种方法之一。
1.使用多绑定转换器。 您的第一个复选框的 ItemsSource 将绑定到一个字符串列表。它的 SelectedItem 将是一个字符串,它是 Dictionary>.
的键
您可以将键和字典都传递给多绑定转换器,并将其 return 字典的键作为列表或数组,如下所示:
public class MyDictionaryValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//first item is our key
string key = values[0] as string;
//second item is our dictionary
Dictionary<string, Dictionary<CustomKey, CustomClass>> dictionary = values[1] as Dictionary<string, Dictionary<CustomKey, CustomClass>>;
//pass our value to be bound to
return dictionary[key].Keys.ToList();
}
}
你知道如何在代码中设置转换器绑定吗?可能需要研究多重绑定,我只在 xaml.
做过
2。您也可以使用中间属性执行此操作 您不必直接绑定到所有内容,您可以在数据对象中创建一个 属性,如下所示:
public class DataContextThatContainsYourDictionary : INotifyPropertyChanged
{
//notifying property that is bound to ItemsSource in the first Combobox
public Dictionary<string, Dictionary<CustomKey, CustomClass>> MyDictionary { get... }
//This is the string that's bound to SelectedItem in the first ComboBox
public string SelectedKey
{
get
{
return selectedKey;
}
set
{
//standard notify like all your other bound properties
if (selectedKey != value)
{
selectedKey = value;
//when this changes, our selection has changed, so update the second list's ItemsSource
SelectedKeys = MyDictionary[SelectedKey].Keys.ToList();
NotifyPropertyChanged("SelectedKey");
}
}
}
//an "intermediatary" Property that's bound to the second Combobox, changes with the first's selection
public List<CustomKey> SelectedKeys { get ... }
这两个结果相同,您最终会将组合框绑定到一个列表。然后,您可以将 DisplayMemberPath 设置为第一个复选框的 T1 或第二个复选框的 T2。
尝试像下面这样设置绑定:您可能还需要为其他两个组合框设置 DisplayMemberPath,具体取决于您要在其中显示的属性。
var c1 = new AutoCompleteComboBox { Name = "c1", DisplayMemberPath = "Key", IsEditable = property.IsEditable, VerticalContentAlignment = VerticalAlignment.Center };
var c2 = new AutoCompleteComboBox { IsEditable = property.IsEditable, VerticalContentAlignment = VerticalAlignment.Center };
var c3 = new AutoCompleteComboBox { IsEditable = property.IsEditable, VerticalContentAlignment = VerticalAlignment.Center };
c1.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source") { Source = MappingService.Instance, Mode = BindingMode.OneWay });
c2.SetBinding(ItemsControl.ItemsSourceProperty, new Binding() { Path = new PropertyPath("SelectedItem.Value.Keys"), ElementName = c1.Name, Mode = BindingMode.OneWay });
c3.SetBinding(ItemsControl.ItemsSourceProperty, new Binding() { Path = new PropertyPath("SelectedItem.Value.Values"), ElementName = c1.Name, Mode = BindingMode.OneWay });
我有三个组合框。三个绑定相同的 ItemsSource.
这个 ItemsSouce 类型是 Dictionary<string, Dictionary<CustomKey, CustomClass>>
自定义键
public struct CustomKey<T1,T2> // T1, T2 is string
{
public readonly T1 Symbol;
public readonly T2 Column;
public CustomKey(T1 key1, T2 key2) { Symbol = key1; Column = key2; }
}
自定义类
public class CustomClass
{
public string Value{get;set}
}
First. FirstComboBox的ItemsSoure是Dictionary.Keys
Second. 我想设置 Second ComboBox 的 Items Source 是 FirstComboBox 的 SelectedItems.
像这样 Dictionary[FirstComboBox.SelectedItem]。按键 T1
Third. ThirdComboBox 的 ItemsSource Dictionary[FirstComboBox.SelectedItem].Keys T2
最后一个。
这是我的代码...
// Source.GetNames 是 ItemsSource.Keys.ToList();
protected virtual FrameworkElement CreateAutoCompleteComboBoxControl(PropertyItem property)
{
var c = new AutoCompleteComboBox();
ContinuityBindablePropertyItem cbp = (property as ContinuityBindablePropertyItem); // cbp is First ComboBox SelectedItem Descriptor. but i don't know how to use...
if (property.DisplayName == "Sheet") // First ComboBox
{
c.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source.GetSheetNames");
}
else if (property.DisplayName == "TestName") // Second ComboBox
{
c.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source.GetSheetNames");
}
else if (property.DisplayName == "Symbol") // Third ComboBox
{
c.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source.GetSheetNames");
}
c.SetBinding(ComboBox.TextProperty, property.CreateBinding());
return c;
}
请帮助我。 我英语说得不好。希望你明白。
谢谢。
编辑
改变方法。
protected virtual FrameworkElement CreateAutoCompleteComboBoxControl(PropertyItem property)
{
StackPanel s = new StackPanel();
var c1 = new AutoCompleteComboBox { Name = "c1", DisplayMemberPath = "Key", IsEditable = property.IsEditable, ItemsSource = property.ItemsSource, VerticalContentAlignment = VerticalAlignment.Center };
var c2 = new AutoCompleteComboBox { IsEditable = property.IsEditable, ItemsSource = property.ItemsSource, VerticalContentAlignment = VerticalAlignment.Center };
var c3 = new AutoCompleteComboBox { IsEditable = property.IsEditable, ItemsSource = property.ItemsSource, VerticalContentAlignment = VerticalAlignment.Center };
c1.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source") { Source = MappingService.Instance, Mode = BindingMode.OneWay });
c2.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Values") { Source = c1.SelectedItem, Mode = BindingMode.OneWay });
c3.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("SelectedItem.Values") { ElementName = c1.Name, Mode = BindingMode.OneWay });
c1.SetBinding(ComboBox.TextProperty, property.CreateBinding());
c2.SetBinding(ComboBox.TextProperty, property.CreateBinding());
c3.SetBinding(ComboBox.TextProperty, property.CreateBinding());
s.Children.Add(c1);
s.Children.Add(c2);
s.Children.Add(c3);
return s;
}
我尝试绑定路径 'Values'、'Value'、'SelectedItem.Value'、'SelectedItem.Values、将源更改为 C1.SelectedItem 或元素名称 = c1...
但是没用
编辑
添加图像。
我对您正在尝试做的事情感到有点困惑,我想我需要更多的代码或示例来理解它。但我会尝试解决一些问题。另外,我习惯了xaml,所以你可能要补上绑定代码的空缺:
First. FirstComboBox's ItemsSoure is Dictionary.Keys
只是为了检查一下,这是有效的吗?
Second. I want to set Second ComboBox's Items Source is FirstComboBox's SelectedItems. like this Dictionary[FirstComboBox.SelectedItem].Keys T1
Third. ThirdComboBox's ItemsSource Dictionary[FirstComboBox.SelectedItem].Keys T2
这两个本质上是同一个问题,你想绑定到Dictionary.Keys,但是有一个组合框显示T1,另一个显示T2?好的,与其尝试将 ComboBox 直接绑定到 Dictionary[FirstComboBox.SelectedItem].Keys T1,我建议使用以下两种方法之一。
1.使用多绑定转换器。 您的第一个复选框的 ItemsSource 将绑定到一个字符串列表。它的 SelectedItem 将是一个字符串,它是 Dictionary>.
的键您可以将键和字典都传递给多绑定转换器,并将其 return 字典的键作为列表或数组,如下所示:
public class MyDictionaryValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//first item is our key
string key = values[0] as string;
//second item is our dictionary
Dictionary<string, Dictionary<CustomKey, CustomClass>> dictionary = values[1] as Dictionary<string, Dictionary<CustomKey, CustomClass>>;
//pass our value to be bound to
return dictionary[key].Keys.ToList();
}
}
你知道如何在代码中设置转换器绑定吗?可能需要研究多重绑定,我只在 xaml.
做过2。您也可以使用中间属性执行此操作 您不必直接绑定到所有内容,您可以在数据对象中创建一个 属性,如下所示:
public class DataContextThatContainsYourDictionary : INotifyPropertyChanged
{
//notifying property that is bound to ItemsSource in the first Combobox
public Dictionary<string, Dictionary<CustomKey, CustomClass>> MyDictionary { get... }
//This is the string that's bound to SelectedItem in the first ComboBox
public string SelectedKey
{
get
{
return selectedKey;
}
set
{
//standard notify like all your other bound properties
if (selectedKey != value)
{
selectedKey = value;
//when this changes, our selection has changed, so update the second list's ItemsSource
SelectedKeys = MyDictionary[SelectedKey].Keys.ToList();
NotifyPropertyChanged("SelectedKey");
}
}
}
//an "intermediatary" Property that's bound to the second Combobox, changes with the first's selection
public List<CustomKey> SelectedKeys { get ... }
这两个结果相同,您最终会将组合框绑定到一个列表。然后,您可以将 DisplayMemberPath 设置为第一个复选框的 T1 或第二个复选框的 T2。
尝试像下面这样设置绑定:您可能还需要为其他两个组合框设置 DisplayMemberPath,具体取决于您要在其中显示的属性。
var c1 = new AutoCompleteComboBox { Name = "c1", DisplayMemberPath = "Key", IsEditable = property.IsEditable, VerticalContentAlignment = VerticalAlignment.Center };
var c2 = new AutoCompleteComboBox { IsEditable = property.IsEditable, VerticalContentAlignment = VerticalAlignment.Center };
var c3 = new AutoCompleteComboBox { IsEditable = property.IsEditable, VerticalContentAlignment = VerticalAlignment.Center };
c1.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Source") { Source = MappingService.Instance, Mode = BindingMode.OneWay });
c2.SetBinding(ItemsControl.ItemsSourceProperty, new Binding() { Path = new PropertyPath("SelectedItem.Value.Keys"), ElementName = c1.Name, Mode = BindingMode.OneWay });
c3.SetBinding(ItemsControl.ItemsSourceProperty, new Binding() { Path = new PropertyPath("SelectedItem.Value.Values"), ElementName = c1.Name, Mode = BindingMode.OneWay });