调用LoadChartFromFile后向TChart添加值触发访问违规错误
问题原因
当使用LoadChartFromFile加载图表时,它会完全替换Chart中原有的所有Series,包括你在设计时创建的Series1。此时原来的Series1对象已经被销毁,内存地址失效,后续再通过Series1添加数据就会触发访问违规。
解决方法
不要直接依赖设计时创建的Series变量,而是从Chart的SeriesList中获取当前有效的Series对象。具体修改如下:
1. 统一按钮点击事件逻辑
所有添加数据的按钮事件,改为从Chart1.Series集合中获取当前有效的Series实例,避免访问已失效的Series1变量:
procedure TForm7.Button1Click(Sender: TObject); var CurrentSeries: TBarSeries; begin // 先判断Chart中是否存在Series,避免空指针 if Chart1.SeriesCount > 0 then begin CurrentSeries := TBarSeries(Chart1.Series[0]); CurrentSeries.Add(40); end; end;
其他按钮(Button2到Button5)只需修改Add的数值,逻辑完全一致。
2. 优化加载逻辑(可选)
在FormCreate中增加文件存在判断,避免首次启动时加载不存在的文件导致异常:
procedure TForm7.FormCreate(Sender: TObject); begin if FileExists('File1') then LoadChartFromFile(TCustomChart(Chart1), 'File1'); end;
修改后的完整代码
unit Unit7; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VclTee.TeeGDIPlus, VCLTee.TeEngine, VCLTee.Series, Vcl.ExtCtrls, VCLTee.TeeProcs, VCLTee.Chart, VCLTee.TeeStore, VCLTee.TeeEdiSeri, Vcl.StdCtrls; type TForm7 = class(TForm) Chart1: TChart; Series1: TBarSeries; Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form7: TForm7; implementation {$R *.dfm} procedure TForm7.Button1Click(Sender: TObject); var CurrentSeries: TBarSeries; begin if Chart1.SeriesCount > 0 then begin CurrentSeries := TBarSeries(Chart1.Series[0]); CurrentSeries.Add(40); end; end; procedure TForm7.Button2Click(Sender: TObject); var CurrentSeries: TBarSeries; begin if Chart1.SeriesCount > 0 then begin CurrentSeries := TBarSeries(Chart1.Series[0]); CurrentSeries.Add(90); end; end; procedure TForm7.Button3Click(Sender: TObject); var CurrentSeries: TBarSeries; begin if Chart1.SeriesCount > 0 then begin CurrentSeries := TBarSeries(Chart1.Series[0]); CurrentSeries.Add(10); end; end; procedure TForm7.Button4Click(Sender: TObject); var CurrentSeries: TBarSeries; begin if Chart1.SeriesCount > 0 then begin CurrentSeries := TBarSeries(Chart1.Series[0]); CurrentSeries.Add(50); end; end; procedure TForm7.Button5Click(Sender: TObject); var CurrentSeries: TBarSeries; begin if Chart1.SeriesCount > 0 then begin CurrentSeries := TBarSeries(Chart1.Series[0]); CurrentSeries.Add(140); end; end; procedure TForm7.FormCreate(Sender: TObject); begin if FileExists('File1') then LoadChartFromFile(TCustomChart(Chart1), 'File1'); end; procedure TForm7.FormDestroy(Sender: TObject); begin SaveChartToFile(Chart1,'File1',True); end; end.
关键说明
- 加载图表后,原设计时的
Series1已被销毁,必须通过Chart1.Series[index]获取当前有效的Series实例。 - 添加
SeriesCount判断是为了处理首次启动且无保存文件的场景,避免空指针异常。
内容的提问来源于stack exchange,提问作者Gustavo Fonseca
相关产品推荐
相关产品推荐

