Delphi:修改StringGrid文本时同步更新SynEdit对应行的方法
实现StringGrid文本修改同步到SynEdit对应行
需求说明
我开发了一款程序,可按规则从SynEdit中的文本搜索错误,并将错误结果显示在StringGrid中。现在需要实现:当修改StringGrid中的文本时,同步修改SynEdit中对应的行。
现有操作流程
- 在SynEdit中打开文件
- 从SynEdit中的文本创建临时文件
- 将临时文件(FileName.tmp)加载到TStringlist中
- 从TStringlist的文本中搜索错误
- 填充StringGrid
现有核心代码
procedure Tform1.SearchDetailErrors(Sender: TObject); var strlError: TStringlist; i: integer; str: string; begin if not DirectoryExists('Duplicates & Errors') then frmMain.CreateDirDuplicates(Sender); if frmMain.SynEdit.Lines.Count >= 1 then frmMain.SynEdit.Lines.SaveToFile('Duplicates & Errors\All Erros ' + ExtractFileName(frmMain.OpenTxtFileDlg.FileName) + '.tmp'); strlError := TStringList.Create; strlError.LoadFromFile('Duplicates & Errors\All Erros ' + ExtractFileName(frmMain.OpenTxtFileDlg.FileName) + '.tmp'); for i := 0 to strlError.Count - 1 do begin strlError.Strings[i] := Trim(strlError.Strings[i]); if CountPos('<', strlError.Strings[i]) <> 1 then begin str := IntToStr(i + 1) + ' | < | ' + strlError.Strings[i]; //str := IntToStr(i + 1) + ' < ' + strlError.Strings[i]; StrLDupl.AddStrings(str); str := ''; CPos := 0; end; if CountPos('>', strlError.Strings[i]) <> 1 then begin str := IntToStr(i + 1) + ' | > | ' + strlError.Strings[i]; StrLDupl.AddStrings(str); str := ''; CPos := 0; end; ... if Odd(CountPos('!', strlError.Strings[i])) then begin str := IntToStr(i + 1) + ' | ! | ' + strlError.Strings[i]; //str := IntToStr(i + 1) + ' " ' + strlError.Strings[i]; StrLDupl.AddStrings(str); str := ''; CPos := 0; end; ... StringGridOptions(Sender); end; procedure Tform1.StringGridOptions(Sender: TObject); begin with SGDetailErrors do ... begin Cells[0, 0] := 'Line № '; Cells[1, 0] := 'Error '; Cells[2, 0] := 'String'; end; FillStringGridResultDetailErrors(Sender); end; procedure Tform1.FillStringGridResultDetailErrors(Sender: TObject); var strlError: TStringList; i: Integer; s: String; begin strlError := TStringList.Create; try strlError.LoadFromFile('Duplicates & Errors\All Errors ' + ExtractFileName(frmMain.OpenTxtFileDlg.FileName) + '.txt'); strlError.QuoteChar := #0; for i := 0 to strlError.Count - 1 do begin with SGDetailErrors do begin Rows[i + 1].Delimiter := '|'; strlError.Strings[i] := StringReplace(strlError.Strings[i], ' ', 'tmp', [rfReplaceAll]); Rows[i + 1].DelimitedText := strlError.Strings[i]; Cells[0, i] := StringReplace(Cells[0, i], 'tmp', '', [rfReplaceAll]); Cells[1, i] := StringReplace(Cells[1, i], 'tmp', '', [rfReplaceAll]); Cells[2, i] := StringReplace(Cells[2, i], 'tmp', ' ', [rfReplaceAll]); end; end; except raise Exception.Create('Error processing file.'); end; strlError.Free; end;
StringGrid界面

同步修改实现方案
核心思路
利用StringGrid的OnSetEditText事件,在单元格文本修改完成后,提取对应行号和修改后的内容,直接更新SynEdit的对应行,同时可同步更新临时文件保持数据一致性。
具体实现代码
procedure Tform1.SGDetailErrorsSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: string); var LineNum: Integer; begin // 仅处理内容列(第2列,索引从0开始) if ACol = 2 then begin // 转换StringGrid中显示的行号为SynEdit的索引(行号从1开始,SynEdit索引从0开始) LineNum := StrToIntDef(SGDetailErrors.Cells[0, ARow], -1); if LineNum > 0 and (LineNum - 1 < frmMain.SynEdit.Lines.Count) then begin // 同步更新SynEdit对应行 frmMain.SynEdit.Lines[LineNum - 1] := Value; // 可选:同步更新临时文件,避免后续搜索时数据不一致 frmMain.SynEdit.Lines.SaveToFile('Duplicates & Errors\All Erros ' + ExtractFileName(frmMain.OpenTxtFileDlg.FileName) + '.tmp'); end; end; end;
注意事项
- 确保StringGrid第0列的行号与SynEdit的行一一对应,无错误
- 增加行号转换的异常处理,防止非法输入导致程序崩溃
- 若需要持久化修改,可在同步后直接保存SynEdit内容到原文件
内容的提问来源于stack exchange,提问作者Gin
相关产品推荐
相关产品推荐

