积极答复者
WPF: Multiple sources

问题
-
WPF 单个控件, 绑定是否可以指定多个源?
是这样的.
有几个列表框 (ListBox) , 分别绑定了 某集合, 提供单一的详细设置.
然后我想再用一个额外的列表框, 汇合这些集合, 统一设置.
大体上是想实现如下的模式:
ListBox1 ---- Binding-> Collection 1
ListBox 2 --- Binding-> Collection 2
....
ListBox n --- Binding-> Collection n
然后, ListBox ----- Binding - > (Collection 1 + Collection 2 + ... + Collection n)
(Collection 1 , Collection 2 , ... Collection n, 都是相同类型的集合)
如果复制所有集合的 Item 到最终的大集合, Memory 会 Double 多, 所以希望有一种方法可以更简单.
Hello, everyone
答案
-
你说的分段Binding是可以实现的,比如我下面的代码:
ObservableCollection<int> col1 = new ObservableCollection<int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }); ObservableCollection<int> col2 = new ObservableCollection<int>(new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 }); ListBox1.ItemsSource = col1; ListBox2.ItemsSource = col2; CollectionContainer container1 = new CollectionContainer(); container1.Collection = col1; CollectionContainer container2 = new CollectionContainer(); container2.Collection = col2; CompositeCollection col3 = new CompositeCollection(); col3.Add(container1); col3.Add(container2); ListBox3.ItemsSource = col3;
另外,因为你原来的问题需要实现ListBox ----- Binding - > (Collection 1 + Collection 2 + ... + Collection n)的功能,所以要一个Convert是必要的,就是将每个collection对应的值都加起来,所以result有一个和的备份是必要的- 已标记为答案 Yeshirow 2009年2月4日 19:44
全部回复
-
用MultiBinding,但是坏处是,还是有一个额外的数据拷贝。
Xaml:
<StackPanel Orientation="Vertical"> <ListBox x:Name="ListBox1" /> <ListBox x:Name="ListBox2" /> <ListBox x:Name="ListBox3" /> </StackPanel>
C#:
ListBox1.DataContext = m_collection1; ListBox2.DataContext = m_collection2; Binding binding1 = new Binding(); binding1.Source = m_collection1; ListBox1.SetBinding(ListBox.ItemsSourceProperty, binding1); Binding binding2 = new Binding(); binding2.Source = m_collection2; ListBox2.SetBinding(ListBox.ItemsSourceProperty, binding2); MultiBinding binding = new MultiBinding(); binding.Converter = new TestConverter(); binding.Bindings.Add(binding1); binding.Bindings.Add(binding2); ListBox3.SetBinding(ListBox.ItemsSourceProperty, binding);
另外TestConverter的源代码:
public class TestConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { ObservableCollection<int> value1 = (ObservableCollection<int>)values[0]; ObservableCollection<int> value2 = (ObservableCollection<int>)values[1]; ObservableCollection<int> result = new ObservableCollection<int>(); for (int i = 0; i < value1.Count; ++i) { result.Add(value1[i] + value2[i]); } return result; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { string[] splitValues = ((string)value).Split(' '); return splitValues; } } -
是否可以先构建一个大集合, 因为此集合是必须的. 用于最终的 ListBox 来呈现.
而将大集合分类, 将每一类(集合的一部分), 作为其他 Control 的数据源.
模式:
FinalListBox ---> FinalCollection
Item1 item2 item3 item4 item5 item6 item7 ..........
----------------- ------------------------- ...
| as collection1 | as collection2
listBox1 listbox2 ...
但是具体如何实现??
或许这可以称作是 WPF 的分段Binding? :)
Hello, everyone -
你说的分段Binding是可以实现的,比如我下面的代码:
ObservableCollection<int> col1 = new ObservableCollection<int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }); ObservableCollection<int> col2 = new ObservableCollection<int>(new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 }); ListBox1.ItemsSource = col1; ListBox2.ItemsSource = col2; CollectionContainer container1 = new CollectionContainer(); container1.Collection = col1; CollectionContainer container2 = new CollectionContainer(); container2.Collection = col2; CompositeCollection col3 = new CompositeCollection(); col3.Add(container1); col3.Add(container2); ListBox3.ItemsSource = col3;
另外,因为你原来的问题需要实现ListBox ----- Binding - > (Collection 1 + Collection 2 + ... + Collection n)的功能,所以要一个Convert是必要的,就是将每个collection对应的值都加起来,所以result有一个和的备份是必要的- 已标记为答案 Yeshirow 2009年2月4日 19:44