【问题标题】:Getting data from Modal forms before it closes在关闭之前从模态表单获取数据
【发布时间】:2011-10-19 12:15:41
【问题描述】:

我有一个模态表单,并在“确定”按钮中处理一些信息,我需要这些信息在称为模态表单的表单中。

我怎样才能在它关闭之前把它拿出来?

或者延迟关闭,直到我说它可以关闭。

【问题讨论】:

标签: delphi modal-dialog


【解决方案1】:

我希望您的“确定”按钮将 ModalResult 设置为 mrOK。如果您想将错误检查添加到 OK 按钮,请将其更改为 mrNone。将OnClick 处理程序添加到执行您需要的任何检查或处理的按钮。如果确定窗体可以关闭,则在OnClick 处理程序中设置Self.ModalResult := mrOK

【讨论】:

  • 恭喜你登顶all time Delphi users
  • 有人知道为什么这个答案有 2 票反对吗?这似乎是解决问题的“延迟关闭直到我说它可以关闭”部分的唯一答案。
  • 我需要在表单关闭之前做一些事情,这解决了我的问题!
【解决方案2】:

您真的需要在表单关闭之前访问这些信息吗?延迟关闭表单会影响应用程序的用户体验(除非它足够快以至于他们没有注意到 - 在这种情况下为什么要延迟它?)

调用者的内存中仍然可以使用已关闭的表单(除非关闭操作是 caFreeOnClose)。因此,您应该能够将公共属性添加到表单中,然后您可以在调用者中访问这些属性。

例如

Type Form2 = Class(TForm)
public
    //Add a public property here
end;

来自调用者:

if Form2.ShowModal = mrOk then
begin
    InformationIWant = Form2.PublicProperty;
end;

【讨论】:

  • 这里有几个问题: 1. Show 不是一个函数。你大概是指ShowModal。 2. 你没有解决问题中关于“延迟关闭,直到我说它可以关闭”的部分。
  • @DavidHeffernan:谢谢大卫,我目前无法访问 Delphi,因此无法检查。我已经更新了答案。我试图解决你的第二点
  • 想要验证数据并阻止表单关闭是很常见的。这必须发生在表单内部,而不是在ShowModal 返回之后。
  • @DavidHeffernan:我认为这个问题不是关于验证数据,而是关于在调用代码中访问对话框的数据。 JamesB 在他的回答中提到了这一点。
  • “除非关闭操作是 caFreeOnClose” - 不幸的是,这将在许多(大多数?)情况下发生。
【解决方案3】:

只是其他人所说的组合。

形式化如何验证和从模式对话框中获取数据是一个好主意。 一遍又一遍地使用相同的技术可以使所有内容更易于维护和阅读。

一个例子:

Type TFormModal = Class(TForm)
  procedure OnOkClick( Sender : TObject);
  function ValidateInterface : boolean;

public
  procedure SetInterface( input data here);
  procedure GetInterface( output data here);

end;

procedure TFormModal.OnOkClick( Sender : TObject);
begin
  if ValidateInterface 
    then modalResult := mrOk
    else modalResult := mrNone;
end;

来自您的主表单:

procedure MainForm.OnShowMyModalFormClick( sender : TObject);
var
  myModal : TFormModal;
begin
  ...
  myModal := TFormModal.Create( nil);
  try
    myModal.SetInterface( ...);
    if (myModal.ShowModal = mrOk) then myModal.GetInterface(...);

  finally
    myModal.Free;
  end;
  ...
end;

【讨论】:

    【解决方案4】:

    大卫的答案的替代方案是使用OnCloseOnCloseQuery 事件。使用OnCloseQuery,您可以通过设置CanClose := false; 来防止表单关闭

    【讨论】:

      【解决方案5】:

      作为JamesB's answer的补充。

      在获取所需信息后,您必须调用 Form2.Free。

      我通常会在第二个表单的单元中添加一个新功能,例如:

      type
        TForm2 = class(TForm)
        private
          { Private declarations }
        public
          { Public declarations }
          InformationIWant : SomeType;
        end;
      
      var
        Form2: TForm2;
      
      function ReturnValue : SomeType
      
      implementation
      
      function ReturnValue : Sometype;
      begin
         try 
           if Form2 = nil then
              Form2 := TForm2.Create(nil);
           Form2.Windowstate := wsNormal;
           Form2.BringToFront;
           SetForegroundWindow(Application.Handle);     
           if Form2.ShowModal then
              Result := InformationIWant
         finally
            FreeAndNil(Form2);
         end;
      end;
      

      【讨论】:

      • FreeAndNil(Form2) 清楚地表明 Form2 可以是 ReturnValue 中的局部变量,而不是全局变量。
      • 重要提示:最好在表单上调用 .Release 而不是 .Free。释放将使表单有机会处理队列中的所有剩余消息。 stackoverflow.com/questions/708847/…
      【解决方案6】:

      假设您要做的不仅仅是简单地了解用户是否在您的模态框中按下了“确定”或“取消”按钮。
      假设您需要在 FromSettings 中为 MainFrom 设置一些参数。

      1. 创建并显示 FormSettings 模式
      2. 当用户在 FormSettings 中按下“确定”(或“应用”)按钮关闭表单时,您会将所有数据从 FormSettings 传输到 MainForm
      3. 最后调用 FormSettings.Close 或更好的 FormSettings.Release(不是 FormSettings.Free)来关闭表单。

      当然,MainFrom 必须有一些公开的(公共)字段,您可以在其中接收来自 FormSettings 的数据,例如:

       FormMain.AlphaBlendValue := FormSettings.spnTransparency;
      

      提示 1:
      您不必将数据从 FormSettings 传输到 MainForm。如果它更适合您,您还可以将数据保存在全局变量或记录中。

      提示 2:
      我个人不使用上面介绍的方法,这种方法是为了在释放 FormSettings 时节省 RAM。
      我实际上从不破坏 SettingsForm。有些人会说这是“可怕的”,但今天的计算机(至少)有 4GB 或 RAM,并且带有一些控件的表单会“浪费”非常少的 RAM。所以,里面的FormSettings一直都是内存。当我需要一些值时,我只是让 MainForm 从 FormSettings 中读取它们。
      再次......这绝对是推荐的方法。这是方便的方法:)您已被警告!

      【讨论】:

        猜你喜欢
        • 2014-07-25
        • 2018-12-18
        • 2020-10-29
        • 2012-07-27
        • 1970-01-01
        • 2021-01-24
        • 2019-06-25
        • 2012-04-11
        • 1970-01-01
        相关资源
        最近更新 更多