如何使用转换器将可观察集合绑定到画布(Canvas)上?该问题涉及IT技术。

3

我有一系列函数,想要在画布上绘制它们。所以我认为绘制这些函数的正确数据类型是 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>...,它会在第一次运行时更改集合,并且会搞乱绑定?
1个回答

3

不要一次性转换整个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 方法也需要进行适应。

非常感谢。运行得非常顺利。 - M.kazem Akhgary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接