我正在使用D3绘制图表。在这一刻,我通过这种方式绑定:
<d3:ChartPlotter x:Name="plotter" ItemsSource="Charts" Margin="20">
我在图表中添加/删除项目,并自动更新绘图仪。效果很好。
问题是我需要绑定几个集合,但显然我不能设置ItemsSource两次。我已经阅读了有关CompositeCollections的内容,但几乎所有文章都基于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的其他方法持开放态度,但是手动将每个子集合中的每个项目添加到Charts我觉得它太麻烦了。谢谢。
编辑:
我正在尝试通过MultiBinding进行,这是转换器的方案
EDIT2:
图表是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语句加农炮在”对象“类型的变量中运行,因为”对象“不包含”GetEnumerator“的公共定义。
答案 0 :(得分:1)
使用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>