使用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
继承一个重要的,有风险的工作,这只是最后的手段。)
不让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 .