扩展WPF工具箱图表中的线条系列以提供数据标记

扩展WPF工具箱图表中的线条系列以提供数据标记,wpf,wpf-controls,data-visualization,wpftoolkit,Wpf,Wpf Controls,Data Visualization,Wpftoolkit,我从WPF工具包DataVisualization复制了一个在折线图上提供数据标记的实现,并对其进行了一些修改。它在数据点旁边显示绘图的值。图表每隔一段时间就会用不同的数据重新绘制自己,并且在这种情况下不会删除数据标记 我从基类中跳过了RemoveDataPoint方法,试图从Canvas中删除TextBlock,但这会引发invalidoOperationException(枚举数无效,因为集合已更改)。我理解异常发生的原因,但当相应的数据点被删除时,如何从画布中删除文本块?这就是我到目前为止

我从WPF工具包DataVisualization复制了一个在折线图上提供数据标记的实现,并对其进行了一些修改。它在数据点旁边显示绘图的值。图表每隔一段时间就会用不同的数据重新绘制自己,并且在这种情况下不会删除数据标记

我从基类中跳过了
RemoveDataPoint
方法,试图从
Canvas
中删除
TextBlock
,但这会引发
invalidoOperationException
(枚举数无效,因为集合已更改)。我理解异常发生的原因,但当相应的
数据点
被删除时,如何从
画布
中删除
文本块
?这就是我到目前为止所做的:

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);
    }
}
公共类DataTagLineSeries:LineSeries
{
私人画布(标签画布),;
专用只读词典_currentLabels=新词典();
公共bool显示标签{get;set;}
公共字符串LabelBindingPath{get;set;}
公共样式标签样式{get;set;}
公共点LabelOffset{get;set;}
应用程序模板()上的公共重写无效
{
base.OnApplyTemplate();
_标签画布=(画布)GetTemplateChild(“绘图区域”);
Clip=null;
}
受保护的覆盖无效更新数据点(数据点数据点)
{
base.UpdateDataPoint(数据点);
if(DisplayLabels&&dataPoint.Visibility==Visibility.Visibility)
Dispatcher.BeginInvoke(DispatcherPriority.Normal,(Action)(()=>CreateLabel(dataPoint));
}
受保护的覆盖void RemoveDataPoint(DataPoint DataPoint)
{
基本。RemoveDataPoint(数据点);
if(_currentLabels.ContainsKey(数据点))
{
_labelscavas.Children.Remove(_currentLabels[dataPoint]);
_currentLabels.Remove(数据点);
}
}
私有void CreateLabel(数据点数据点)
{
文本块标签;
if(_currentLabels.ContainsKey(数据点))
{
标签=_currentLabels[dataPoint];
}
其他的
{
label=新的TextBlock();
_labelscavas.Children.Add(标签);
_currentLabels.Add(数据点、标签);
label.Style=标签样式;
var binding=LabelBindingPath!=null
?新绑定(LabelBindingPath){Source=dataPoint.DataContext}
:新绑定(“DependentValue”){Source=dataPoint};
BindingOperations.SetBinding(标签,TextBlock.TextProperty,绑定);
}
var coordinateY=Canvas.GetTop(dataPoint)+LabelOffset.Y;
var coordinateX=Canvas.GetLeft(dataPoint)+LabelOffset.X;
Canvas.SetTop(标签、坐标);
Canvas.SetLeft(标签,坐标);
}
}