如何使用转换器将可观察集合绑定到画布
本文关键字:绑定 集合 观察 何使用 转换器 | 更新日期: 2023-09-27 18:35:39
我有一个函数集合,我想把它们绘制在画布上。所以我认为绘制这些函数的正确数据类型是 Polyline
.
所以我需要一个转换器将这些功能转换为折线集合,并最终在画布上显示它们。
下面是 XAML 代码。
<ItemsControl ItemsSource="{Binding WaveCollection,
RelativeSource ={RelativeSource FindAncestor, AncestorType={x:Type Window}},
Converter={StaticResource PlotterConverter}}" Margin="10,10,0,239" HorizontalAlignment="Left" Width="330">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="GhostWhite" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
这是转换器的一部分,它将波形转换为折线。绑定模式是单向的。
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var collection = value as IEnumerable<Waveform>;
return new ObservableCollection<Polyline>(GetPlots(collection));
}
但是,当我放置断点时,我注意到它仅在程序启动时触发一次。集合是空的,所以没有什么特别的事情发生,但在那之后,当我将项目添加到集合时,什么也没发生。不会触发任何事件。为什么?
为了确保我还将此代码添加到转换器中,以查看它是否真的触发,但什么也没发生。
var collection = value as ObservableCollection<Waveform>;
collection.Clear(); // this is supposed to clear collection. if binding works correct!
//...
请注意,我还将此集合绑定到listview
中,以显示波浪的信息,这些信息在集合更新时工作正常。
编辑:
我想问题是这部分return new ObservableCollection<Polyline>...
在第一次运行时更改集合并会搞砸绑定?
与其一次转换整个ObservableCollection
,不如使用一次处理一个项目的转换器。
在这种情况下,这意味着您可以通过在 XAML 中定义ItemsControl
的ItemTemplate
来指定每个项应显示为的控件类型:
<ItemsControl ItemsSource="{Binding WaveCollection,
RelativeSource ={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Margin="10,10,0,239" HorizontalAlignment="Left" Width="330">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="GhostWhite" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Polyline Points="{Binding, Converter={StaticResource PlotterConverter}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
PlotterConverter
现在将单独传递每个项目,因此它需要做的就是将Waveform
对象转换为 PointCollection
类型的对象(因为 Polyline
的 Points
属性是 PointCollection
类型):
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var item = value as Waveform;
return new PointCollection(GetPlot(item));
}
当然,GetPlot
方法也需要调整。