撤消图表中系列的操作
Undo operation for series in chart
我想在图表中多次更改一些 Yvalues[0] 后恢复以前的系列。所以我已经使用备忘录模式实现了撤消操作。
但是在 运行 时它不工作并且没有错误。下面是发起人、纪念品和看守人。
public class Originator
{
private Series _series = new Series();
public Originator(Series series)
{
_series = series;
}
public Series OSeries
{
get
{
return _series;
}
set
{
_series = value;
}
}
public Memento SaveSeries()
{
return new Memento(_series);
}
public void RestoreSeries(Memento m)
{
this._series = m.MMseries;
}
}
public class Memento
{
private Series _series =new Series();
public Memento(Originator org)
{
this._series = org.OSeries;
}
public Memento(Series mseries)
{
_series = mseries;
}
public Series MMseries
{
get
{
return _series;
}
set
{
_series = value;
}
}
}
public class Caretaker
{
// private static Caretaker _instance;
// public Caretaker() { }
private Memento chartMemento;
public Memento Memento
{
get
{ return chartMemento; }
set
{ chartMemento = value; }
}
}
在 public 部分 class Form1 中创建对象:Form
Originator _org;
Caretaker taker = new Caretaker();
从文件加载图表时,open_file 函数包含此代码:
_org = new Originator(global_series); //For undo/redo operation
while (chart1.Series.Count > 0) { chart1.Series.RemoveAt(0); }
chart1.Series.Add(global_series);
taker.Memento = _org.SaveSeries();
对于Undo_button:
_org.RestoreSeries(taker.Memento);
while (chart1.Series.Count > 0) { chart1.Series.RemoveAt(0); }
global_series = _org.OSeries;
chart1.Series.Add(global_series);
Series
是一个 reference 变量。
因此,您所做的所有更改都将针对该系列,并且您拥有的所有参考文献都将指向同一个(原始)系列。
花哨的模式,虽然它们可能很有用,但不能替代基础知识。要允许 undo/redo,您需要 data 的 copy,而不是 参考!
请注意 Series
没有 Clone
方法。
所以你需要自己动手;在您的情况下,这归结为 复制点数..
但对于更一般的情况,您可能希望复制其他系列属性,最著名的是 ChartType
,但基本上您为准备 Series
所做的一切。也许以工厂模式创建它..?
但是 还要注意 DataPoint
有一个 Clone
方法。因此,您可以像这样更改 Originator
构造函数:
public Originator(Series series)
{
//_series = series;
foreach (var dp in series.Points) _series.Points.Add(dp.Clone());
}
一切都会按预期开始工作。但是你也需要像这样进行恢复,否则你会指向保存的系列,接下来的更改会改变它而不是图表系列。:
public void RestoreSeries(Memento m)
{
// this._series = m.MMseries;
this._series.Points.Clear();
foreach (var dp in m.MMseries.Points) this._series.Points.Add(dp);
}
顺便说一句:要清除所有系列,请使用 chart.Series.Clear()
!
使用 Memento Pattern 进行多次撤消操作
管理员代码:
public class Caretaker
{
private Memento chartMemento;
public Memento Memento
{
get
{ return chartMemento; }
set
{ chartMemento = value; }
}
}
纪念品代码:
public class Memento
{
private Series _series =new Series();
public Memento(Originator org)
{
this._series.Points.Clear();
foreach (var dp in org.OSeries.Points) this._series.Points.Add(dp.Clone());
}
public Memento(Series mseries)
{
this._series.Points.Clear();
foreach (var dp in mseries.Points) this._series.Points.Add(dp.Clone());
}
public Series MMseries
{
get
{
return _series;
}
set
{
_series = value;
}
}
}
创始人代码
public class Originator{
private Series _series = new Series();
public Originator() { }
public Originator(Series series)
{
// _series = series;
_series.Points.Clear();
foreach (var dp in series.Points) _series.Points.Add(dp.Clone());
}
public Series OSeries
{
get
{
return _series;
}
set
{
_series = value;
}
}
public Memento SaveSeries()
{
return new Memento(_series);
}
public void RestoreSeries(Memento m)
{
//this._series = m.MMseries;
this._series.Points.Clear();
foreach (var dp in m.MMseries.Points) this._series.Points.Add(dp);
this._series.ChartType = SeriesChartType.Line;
}
}
在 Form1 中声明对象列表及其计数器
Orginator _org;
List<Originator> list_org = new List<Originator>();
List<Caretaker> list_taker = new List<Caretaker>();
int obj_counter = 0;
Do 操作代码
list_org.Add(_org = new Originator(global_series));
Caretaker ct = new Caretaker();
ct.Memento = list_org[obj_counter++].SaveSeries();
list_taker.Add(ct);
撤消操作代码:
if (obj_counter > 0)
{
list_org[--obj_counter].RestoreSeries(list_taker[obj_counter].Memento);
global_series.Points.Clear();
foreach (var dp in list_org[obj_counter].OSeries.Points)
global_series.Points.Add(dp);
}
我想在图表中多次更改一些 Yvalues[0] 后恢复以前的系列。所以我已经使用备忘录模式实现了撤消操作。
但是在 运行 时它不工作并且没有错误。下面是发起人、纪念品和看守人。
public class Originator
{
private Series _series = new Series();
public Originator(Series series)
{
_series = series;
}
public Series OSeries
{
get
{
return _series;
}
set
{
_series = value;
}
}
public Memento SaveSeries()
{
return new Memento(_series);
}
public void RestoreSeries(Memento m)
{
this._series = m.MMseries;
}
}
public class Memento
{
private Series _series =new Series();
public Memento(Originator org)
{
this._series = org.OSeries;
}
public Memento(Series mseries)
{
_series = mseries;
}
public Series MMseries
{
get
{
return _series;
}
set
{
_series = value;
}
}
}
public class Caretaker
{
// private static Caretaker _instance;
// public Caretaker() { }
private Memento chartMemento;
public Memento Memento
{
get
{ return chartMemento; }
set
{ chartMemento = value; }
}
}
在 public 部分 class Form1 中创建对象:Form
Originator _org;
Caretaker taker = new Caretaker();
从文件加载图表时,open_file 函数包含此代码:
_org = new Originator(global_series); //For undo/redo operation
while (chart1.Series.Count > 0) { chart1.Series.RemoveAt(0); }
chart1.Series.Add(global_series);
taker.Memento = _org.SaveSeries();
对于Undo_button:
_org.RestoreSeries(taker.Memento);
while (chart1.Series.Count > 0) { chart1.Series.RemoveAt(0); }
global_series = _org.OSeries;
chart1.Series.Add(global_series);
Series
是一个 reference 变量。
因此,您所做的所有更改都将针对该系列,并且您拥有的所有参考文献都将指向同一个(原始)系列。
花哨的模式,虽然它们可能很有用,但不能替代基础知识。要允许 undo/redo,您需要 data 的 copy,而不是 参考!
请注意 Series
没有 Clone
方法。
所以你需要自己动手;在您的情况下,这归结为 复制点数..
但对于更一般的情况,您可能希望复制其他系列属性,最著名的是 ChartType
,但基本上您为准备 Series
所做的一切。也许以工厂模式创建它..?
但是 还要注意 DataPoint
有一个 Clone
方法。因此,您可以像这样更改 Originator
构造函数:
public Originator(Series series)
{
//_series = series;
foreach (var dp in series.Points) _series.Points.Add(dp.Clone());
}
一切都会按预期开始工作。但是你也需要像这样进行恢复,否则你会指向保存的系列,接下来的更改会改变它而不是图表系列。:
public void RestoreSeries(Memento m)
{
// this._series = m.MMseries;
this._series.Points.Clear();
foreach (var dp in m.MMseries.Points) this._series.Points.Add(dp);
}
顺便说一句:要清除所有系列,请使用 chart.Series.Clear()
!
使用 Memento Pattern 进行多次撤消操作
管理员代码:
public class Caretaker
{
private Memento chartMemento;
public Memento Memento
{
get
{ return chartMemento; }
set
{ chartMemento = value; }
}
}
纪念品代码:
public class Memento
{
private Series _series =new Series();
public Memento(Originator org)
{
this._series.Points.Clear();
foreach (var dp in org.OSeries.Points) this._series.Points.Add(dp.Clone());
}
public Memento(Series mseries)
{
this._series.Points.Clear();
foreach (var dp in mseries.Points) this._series.Points.Add(dp.Clone());
}
public Series MMseries
{
get
{
return _series;
}
set
{
_series = value;
}
}
}
创始人代码
public class Originator{
private Series _series = new Series();
public Originator() { }
public Originator(Series series)
{
// _series = series;
_series.Points.Clear();
foreach (var dp in series.Points) _series.Points.Add(dp.Clone());
}
public Series OSeries
{
get
{
return _series;
}
set
{
_series = value;
}
}
public Memento SaveSeries()
{
return new Memento(_series);
}
public void RestoreSeries(Memento m)
{
//this._series = m.MMseries;
this._series.Points.Clear();
foreach (var dp in m.MMseries.Points) this._series.Points.Add(dp);
this._series.ChartType = SeriesChartType.Line;
}
}
在 Form1 中声明对象列表及其计数器
Orginator _org;
List<Originator> list_org = new List<Originator>();
List<Caretaker> list_taker = new List<Caretaker>();
int obj_counter = 0;
Do 操作代码
list_org.Add(_org = new Originator(global_series));
Caretaker ct = new Caretaker();
ct.Memento = list_org[obj_counter++].SaveSeries();
list_taker.Add(ct);
撤消操作代码:
if (obj_counter > 0)
{
list_org[--obj_counter].RestoreSeries(list_taker[obj_counter].Memento);
global_series.Points.Clear();
foreach (var dp in list_org[obj_counter].OSeries.Points)
global_series.Points.Add(dp);
}