使用CurveList的预先存在的跟踪类

本文关键字:跟踪 存在 CurveList 使用 | 更新日期: 2023-09-27 18:05:56

很久以前,我建立了一个跟踪类来管理一个测量点列表:

public class TraceXYZ : CollectionBase, ICloneable { … }

很久以后,在TraceXYZ在我的软件中广泛使用之后,我开始使用优秀的绘图包ZedGraph。因此,我添加了一个TraceXYZ方法.toLineItem(),它返回一个与zedGraph GraphPane的CurveList属性兼容的LineItem

随着我越来越多地使用这个特性,我发现在需要更新TraceXYZ对象并在zedGraph窗格中显示修改后的值的应用程序中,它可能相当笨拙。因为它目前存在,我必须在CurveList中跟踪TraceXYZ的相关LineItem,删除它,然后创建并添加一个反映修改后的TraceXYZ的新LineItem

更可取的是允许CurveList直接在TraceXYZ上操作的能力,但是因为我已经继承了CollectionBase,所以我也不能继承LineItem。而且,我在zedGraph中找不到相关的接口(比如ILineItem)来实现这个功能。

最后,我重新编码了TraceXYZ的核心,以使用zedGraph PointPair对象列表,然后尝试通过引用将它们复制到LineItem中,以便对TraceXYZ中原始点的修改将反映在zedGraph窗格中。然而,这并没有奏效。显然,CurveList.AddPoint()方法克隆点,它们不再引用TraceXYZ中的原件。

所以…有什么想法可以让我完成这样的事情吗?理想情况下,作为一个例子,我希望能够做以下事情:

TraceXYZ trace = new TraceXYZ();
... populate trace points ...

pane.CurveList.Add( trace );
zedGraph.AxisChange( );
zedGraph.Refresh( );
trace[index].Y = aNewValue;
zedGraph.AxisChange( );
zedGraph.Refresh( );

,并将Y的新值反映在zedGraph窗格中。

(由于我广泛地使用TraceXYZ,因此对其进行改革以从LineItem继承一个重要的,有风险的工作,这只是最后的手段。)

使用CurveList的预先存在的跟踪类

不让TraceXYZ从LineItem派生,我将使用另一种方法:

使用其Points属性将LineItem与IPointList关联。每次在ZedGraph控件(或GraphPane对象)上调用Invalidate方法时,ZedGraph查询IPointList以获得要显示的整个列表点。

这是使ZedGraph独一无二的主要特性之一。

这意味着您可以使您的自定义集合类继承IPointList,并将其直接关联到您的LineItem。基本上,你必须重写一个Count属性,一个返回PointPair对象的Indexer,一个可以被{ return this; }愚弄的Clone函数,就是这样。

不再需要填充点列表,ZedGraph将直接从您自己的集合中获得它。

作为一个例子,我设计了一个GenericPointList,它允许将几乎所有类型的列表投影为IPointList,使用lambda选择器检索X和Y值。因此,您可以看到实现自己的IPointList是多么容易。

很可能你只需要实现索引器:

public class TraceXYZ : CollectionBase, ICloneable, IPointList {
    public PointPair this[int index] {
        get {
            // return new PointPair(double X, double Y);
            return new PointPair(...
        }
    }
    public object Clone() {
        // Apparently, your objects implements ICloneable, so you likely implemented Clone already
    }
    public int Count {
        get {
            // Your objects implements CollectionBase, so Count is likely already implemented
        }
    }
}

在某些初始化代码中:

TraceXYZ trace = new TraceXYZ();
...
var li = new LineItem(...
li.Points = TraceXYZ;
pane.CurveList.Add(li);

然后在某一时刻:

trace[index].Y = aNewValue;
zedGraph.AxisChange( );
zedGraph.Refresh( );

详细说明Larry的回答,下面是我如何实现他的解决方案:

由于TraceXYZ类已经有一个索引器,所以我将PointPair的索引器实现为显式实现:

    PointPair IPointList.this[int idx] {
        get {
            PointXYZ point = (PointXYZ)List[idx];
            return point as PointPair;
        }
    }

我还扩展了ZedGraph CurveList类如下。这允许处理其他辅助属性等(如trace color)。

    public static void Add( this CurveList curves, TraceXYZ trace ) {
        LineItem li = new LineItem("");
        li.Points = trace;
        li.Color = trace.plotInfo.color;
        ...
        curves.Add( li );
        return;
    }

这允许调用上下文直接将TraceXYZ类对象添加到ZedGraph曲线列表中:

TraceXYZ trace = new TraceXYZ();

…在这里填充跟踪并设置辅助属性…

pane.CurveList.Add(trace);

…在以后的某个时候……

trace[index].Y = aNewValue;
zedGraph.AxisChange( );
zedGraph.Refresh( );

,瞧,窗格图更新了。

再次感谢Larry,马克。r .