如何使用转换器将可观察集合绑定到画布

本文关键字:绑定 集合 观察 何使用 转换器 | 更新日期: 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 中定义ItemsControlItemTemplate来指定每个项应显示为的控件类型:

<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 类型的对象(因为 PolylinePoints 属性是 PointCollection 类型):

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    var item = value as Waveform;
    return new PointCollection(GetPlot(item));
}

当然,GetPlot方法也需要调整。