很久以前,我构建了一个跟踪类来管理测量点列表:
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
一项重大的,有风险的努力,这只是最后的手段。)
答案 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。