绑定到多个源
本文关键字:绑定 | 更新日期: 2023-09-27 18:17:59
我正在用D3绘制图表。现在我是这样绑定的:
<d3:ChartPlotter x:Name="plotter" ItemsSource="Charts" Margin="20">
和我添加/删除项目到图表和绘图仪自动更新。非常好。
问题是,我需要从几个集合绑定,但显然我不能设置ItemsSource两次。我读过一些关于compositecollection的文章,但是几乎每一篇文章都是基于StaticResource的,这不是我的情况。
<d3:ChartPlotter x:Name="plotter"Margin="20">
<d3:ChartPlotter.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Charts}" />
<CollectionContainer Collection="{Binding Charts2}" />
</CompositeCollection>
</d3:ChartPlotter.ItemsSource>
这段代码可以编译,但是绑定不起作用。
我已经搜索了很多,但令人惊讶的是,我还没有找到答案。我认为这在WPF中是一个常见的任务。我对将多个集合绑定到单个ItemsSource的其他方式开放,但手动将每个子集合中的每个项目添加到图表中,我认为这太麻烦了。谢谢你!
编辑:我尝试通过MultiBinding来实现这是转换器的方案
EDIT2:
Charts是一个ObservableCollection<LineGraph>
public class ConcatConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
ObservableCollection<LineGraph> enumerables = new ObservableCollection<LineGraph>();
foreach (LineGraph line in values[0])
{
enumerables.Add(line);
}
foreach (LineGraph line in values[1])
{
enumerables.Add(line);
}
return enumerables;
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
return null;
}
}
我不能编译,因为这个错误:"foreach语句不能在"object"类型的变量中操作,因为"object"不包含"GetEnumerator"的公共定义。
使用MultiBinding
。首先,做一个你想做的转换器:
public class ConcatConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
List<IEnumerable> enumerables = new List<IEnumerable>();
foreach (object obj in values)
{
IEnumerable temp = obj as IEnumerable;
if (temp == null) throw new ArgumentException();
enumerables.Add(temp);
}
List<dynamic> enDynamic = new List<dynamic>();
enDynamic.AddRange(enumerables);
return Concat((dynamic)enDynamic);
}
private IEnumerable<T> Concat<T>(params IEnumerable<T>[] toConcat)
{
return toConcat.Aggregate((a, b) => a.Concat(b));
}
private IEnumerable Concat(params IEnumerable[] toConcat)
{
ArrayList temp = new ArrayList();
foreach (IEnumerable x in toConcat)
{
foreach (object n in x)
{
temp.Add(n);
}
}
return temp;
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
return null;
}
}
(非通用的,但我不想使用钝量的反射)
然后将其添加到窗口的资源中:
<!--in your window declaration-->
xmlns:local="clr-namespace:YourNameSpace"
<!--after that-->
<Window.Resources>
<ttp:ConcatConverter x:Key="Concat"/>
</Window.Resources>
<!--finally:-->
<d3:ChartPlotter.ItemsSource>
<MultiBinding Converter="{StaticResource ResourceKey=Concat}">
<Binding Source="Charts"/>
<Binding Source="Charts2"/>
</MultiBinding>
</d3:ChartPlotter.ItemsSource>