【问题标题】:How to bind observable collection to canvas with converter如何使用转换器将可观察集合绑定到画布
【发布时间】:2016-02-22 17:08:44
【问题描述】:

我有一组函数,我想将它们绘制在画布上。所以我认为绘制这些函数的正确数据类型是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 以显示在集合更新时可以正常工作的 wave 信息。

编辑:

我想问题是这部分 return new ObservableCollection&lt;Polyline&gt;... 在第一次运行时会更改集合并会弄乱绑定?

【问题讨论】:

    标签: c# wpf canvas data-binding


    【解决方案1】:

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

    【讨论】:

    • 非常感谢。像魅力一样工作。
    猜你喜欢
    • 1970-01-01
    • 2013-05-21
    • 2020-05-19
    • 1970-01-01
    • 2010-11-18
    • 2020-12-29
    • 2011-02-16
    • 2011-12-03
    • 1970-01-01
    相关资源
    最近更新 更多