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

时间:2016-09-06 13:11:35

标签: c# plot zedgraph

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

public class TraceXYZ : CollectionBase, ICloneable { … }

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

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

最好是允许CurveList直接在TraceXYZ上操作的功能,但由于我已经从CollectionBase继承,我不能继承LineItem太。更多,我在zedGraph中找不到可以找到的相关接口(例如ILineItem),这将允许我实现该功能。

最后,我重新编写了TraceXYZ的内容,以使用zedGraph PointPair对象列表,然后尝试通过引用将它们复制到LineItem中,以便对TraceXYZ中的原始点进行修改{1}}将反映在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一项重大的,有风险的努力,这只是最后的手段。)

2 个答案:

答案 0 :(得分:1)

我没有使用LineItem派生TraceXYZ,而是使用另一种方法:

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

这是使ZedGraph独一无二的主要功能之一。

这意味着您可以使自定义集合类继承自IPointList并将其直接关联到您的LineItem。基本上,您必须覆盖Count属性,返回PointPair对象的索引器,可以被Clone欺骗的{ return this; }函数,这就是它

不再需要填充点列表,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( );

答案 1 :(得分:1)

详细说明拉里的回答,以下是我如何实施他的解决方案:

由于TraceXYZ类已有索引器,因此我将PointPair的索引器实现为显式实现:

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

我还扩展了ZedGraph CurveList类,如下所示。这允许处理其他辅助属性等(如跟踪颜色)。

    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( );

并且瞧,窗格图已更新。

再次感谢拉里, -Mark R。