如何绑定许多ComboBox的ItemsSoure彼此连接

时间:2016-03-30 07:41:03

标签: wpf binding descriptor

我有三个ComboBox。 Threre与ItemsSource绑定。

此ItemsSouce类型为Dictionary<string, Dictionary<CustomKey, CustomClass>>

CustomKey

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

CustomClass

public class CustomClass
{
    public string Value{get;set}
}

首先。 FirstComboBox的ItemsSoure是 Dictionary.Keys

第二。我想设置Second ComboBox的项目来源是FirstComboBox的SelectedItems。如此字典[FirstComboBox.SelectedItem] .Keys T1

第三。:ThirdComboBox的ItemsSource 字典[FirstComboBox.SelectedItem] .Key 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;
    }

我尝试绑定路径&#39;值&#39;,&#39;值&#39;,&#39; SelectedItem.Value&#39;,&#39; SelectedItem.Values,将源更改为C1.SelectedItem或元素名称= c1 ...

但它不起作用

修改
添加图片。 enter image description here

2 个答案:

答案 0 :(得分:1)

我对你想要做的事情感到有点困惑,我想我需要更多的代码,或者一个例子来了解它。但我会尝试解决一些问题。此外,我习惯了xaml,所以你可能需要填补绑定代码的空白:

  

首先。 FirstComboBox的ItemsSoure是Dictionary.Keys

只是检查一下,这有效吗?

  

二。我想设置Second ComboBox的Items Source是   FirstComboBox的SelectedItems。像这样   字典[FirstComboBox.SelectedItem] .Keys T1

     

第三。 ThirdComboBox的ItemsSource   字典[FirstComboBox.SelectedItem] .Keys T2

这两个基本上是同一个问题,你想绑定到Dictionary.Keys,但有一个组合框显示T1和另一个T2?好的,我没有尝试将ComboBox直接绑定到Dictionary [FirstComboBox.SelectedItem] .Keys T1,而是建议使用两种方法中的一种。

<强> 1。使用多重绑定转换器。您的第一个复选框的ItemsSource将绑定到字符串列表。这是它的SelectedItem将是一个字符串,它是Dictionary&gt;。

的关键

您可以将密钥和字典传递给多重绑定转换器,并将字典的键作为列表或数组返回:

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

这两者都有相同的结果,你最终会将你的ComboBox绑定到List。然后,您可以将DisplayMemberPath设置为第一个复选框的T1或第二个复选框的T2。

答案 1 :(得分:1)

尝试设置如下所示的绑定:您可能还需要为其他两个组合框设置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 });