0

好的(和坏的)旧 Delphi教会了我们构建应用程序的“经典”方式,因为我们在 IDE“后面”编写代码的方式。

基于这个范例,我前段时间构建了一个库,它允许我使用一行代码将 GUI 保存/加载到 INI 文件。

LoadForm(FormName)

砰!就是这样!没有更多的 INI 文件!

该库仅保存“相关”属性。例如,对于 aTCheckBox它只保存它的Checked属性而不是它的Coloror Top/Left。但这绰绰有余。

保存表格没有问题。但是,我在应用程序初始化期间遇到了“问题”。它们不是问题,但初始化代码不是那么好/优雅。

例如,当我分配Checkbox1.Checked := True它时,它将触发OnClick事件(假设在设计时未选中该复选框)。但是赋值False(自然)不会触发OnClick事件。

因此,我必须手动调用CheckBox1Click(Sender)afterSaveForm(FormName)以确保无论在什么代码中CheckBox1Click,它都会被初始化。但这引发了另一个问题。在CheckBox1Click(Sender)应用程序启动期间可能会调用两次(一次是SaveForm我的手动)。

当然,理论上程序的逻辑应该放在单独的对象中,并与 GUI 分离。但即使我们这样做,初始化问题仍然存在。您从磁盘加载对象的属性并将它们分配给 GUI。当您将对象中的任何值设置为 时Checkbox1,它将(或不)调用CheckBox1Click(Sender)将值设置回对象。

在应用启动时:

procedure TForm.FormCreate (Sender: TObject);
begin
  LogicObject.Load(File); // load app logic
  Checkbox1.Checked := LogicObject.Checked; // assign object to GUI
end;

procedure TForm.CheckBox1Click(Sender: TObject);
begin
  LogicObject.Checked := Checkbox1.Checked; 
end;

可能解决方案涉及为表单上的每个控件编写这样的内容:

OldEvent := CheckBox1.OnClick;
CheckBox1.OnClick := Nil;
CheckBox1.Checked := something;
CheckBox1.OnClick := OldEvent;

不优雅。

问题:
您如何解决这个特定问题,或者在将您的 GUI 保存到磁盘/从磁盘恢复时,您的方法是什么?

4

1 回答 1

2

这是从一开始就在某些组件中困扰我的事情之一。我所知道的是 3 个选项,除了 @David 所说的将 GUI 和业务逻辑分开,这并不总是一个选项。

  1. 正如您在上面所写,始终取消分配事件,以免它们被触发
  2. 使用非触发事件,例如OnMouseDownOnMouseUp
  3. 或我使用的类似解决方案,我认为是最优雅的

创建一个FormPreparing在初始化期间设置的全局变量,并在事件开始时检查其值,如下所示。

procedure TForm.FormCreate (Sender: TObject);
begin
  FormPreparing := True;
  try    
    LogicObject.Load(File); // load app logic
    Checkbox1.Checked := LogicObject.Checked; // assign object to GUI
  finally
    FormPreparing := False;
  end;
end;

procedure TForm.CheckBox1Click(Sender: TObject);
begin
  if FormPreparing then
    Exit;
  LogicObject.Checked := Checkbox1.Checked;
end;
于 2018-01-10T11:02:54.063 回答