在WPF Toolkit图表中扩展LineSeries以提供数据标记

时间:2013-01-28 10:30:36

标签: wpf wpf-controls data-visualization wpftoolkit

我复制了一个我发现的实现,该实现在WPF工具包DataVisualization的折线图上提供数据标记并稍微改变了一下。它显示数据点旁边的图的值。图表每隔一段时间就会重新绘制不同的数据,并且在发生这种情况时不会删除数据标记。

我过度使用基类中的RemoveDataPoint方法尝试从TextBlock中移除Canvas,但这会抛出InvalidOperationException(枚举器不是有效,因为集合已更改)。我理解为什么会发生异常,但如果删除相应的TextBlocks,如何从Canvas删除DataPoint?这就是我到目前为止所做的:

public class DataTagLineSeries : LineSeries
{
    private Canvas _labelsCanvas;

    private readonly Dictionary<DataPoint, TextBlock> _currentLabels = new Dictionary<DataPoint, TextBlock>();

    public bool DisplayLabels { get; set; }
    public string LabelBindingPath { get; set; }
    public Style LabelStyle { get; set; }
    public Point LabelOffset { get; set; }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        _labelsCanvas = (Canvas)GetTemplateChild("PlotArea");

        Clip = null;
    }

    protected override void UpdateDataPoint(DataPoint dataPoint)
    {
        base.UpdateDataPoint(dataPoint);

        if (DisplayLabels && dataPoint.Visibility == Visibility.Visible)
            Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => CreateLabel(dataPoint)));
    }

    protected override void RemoveDataPoint(DataPoint dataPoint)
    {
        base.RemoveDataPoint(dataPoint);

        if (_currentLabels.ContainsKey(dataPoint))
        {
            _labelsCanvas.Children.Remove(_currentLabels[dataPoint]);
            _currentLabels.Remove(dataPoint);
        }
    }

    private void CreateLabel(DataPoint dataPoint)
    {
        TextBlock label;

        if (_currentLabels.ContainsKey(dataPoint))
        {
            label = _currentLabels[dataPoint];
        }
        else
        {
            label = new TextBlock();

            _labelsCanvas.Children.Add(label);

            _currentLabels.Add(dataPoint, label);

            label.Style = LabelStyle;

            var binding = LabelBindingPath != null
                                    ? new Binding(LabelBindingPath) { Source = dataPoint.DataContext }
                                    : new Binding("DependentValue") { Source = dataPoint };

            BindingOperations.SetBinding(label, TextBlock.TextProperty, binding);
        }

        var coordinateY = Canvas.GetTop(dataPoint) + LabelOffset.Y;
        var coordinateX = Canvas.GetLeft(dataPoint) + LabelOffset.X;

        Canvas.SetTop(label, coordinateY);
        Canvas.SetLeft(label, coordinateX);
    }
}

0 个答案:

没有答案