在同一个应用程序中更改另一个独立表单上的控件状态

时间:2018-04-06 22:55:39

标签: forms delphi

场合

  • 具有2个表单和1个DataModule单元的应用程序
  • 包含表单的两个单元都具有“uses”中的DataModule。包含Form1的单元在“使用”
  • 中包含Form2
  • Form1上有两个按钮
  • 两个表单同时显示,Form1不是Form2的父级,反之亦然

我需要什么

我需要能够通过Form2上的操作来控制Form1上两个按钮的状态。

我做了什么

我在Form1上使用了一个计时器,连续(250ms)检查DataModule中的一个变量,并根据它的值,它改变了Form1上按钮的状态。然后我从Form2修改DataModule中的变量。

DataModule中的变量:

public
  BtnToDisable: string;

Form1上的计时器:

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i: integer;
begin
  if Datamodule4.BtnToDisable = 'All' then
    for i := 0 to Form1.ControlCount - 1 do
    begin
      if Form1.Controls[i].ClassType = TButton then
        Form1.Controls[i].Enabled := False;
    end
  else if Datamodule4.BtnToDisable = 'None' then
    for i := 0 to Form1.ControlCount - 1 do
    begin
      if Form1.Controls[i].ClassType = TButton then
        Form1.Controls[i].Enabled := True;
    end
  else if Datamodule4.BtnToDisable = 'Button1' then
    for i := 0 to Form1.ControlCount - 1 do
    begin
      if Form1.Controls[i].Name = 'Button1' then
        Form1.Controls[i].Enabled := False;
    end
  else if Datamodule4.BtnToDisable = 'Button2' then
    for i := 0 to Form1.ControlCount - 1 do
    begin
      if Form1.Controls[i].Name = 'Button2' then
        Form1.Controls[i].Enabled := False;
    end;
end;

Form2上的操作:

DataModule4.BtnToDisable := 'All'     // All, None, "name"
DataModule4.BtnToDisable := 'Button1' // All, None, "name"
...

问题

嗯,它可以工作,但是在一个更复杂的场景中,有很多按钮可以启用/禁用,更多表单和更多可能的组合(启用三个特定按钮,禁用所有其他按钮等),它会得到复杂,难以维护。 有没有办法直接访问Form1上的那些按钮,考虑到我没有可从Form2访问的Form1对象?

1 个答案:

答案 0 :(得分:4)

您始终可以访问每个Form对象,即使您没有直接use他们的单位。所有创建的TForm个对象都存储在Forms单元中全局Forms[]对象的Screen属性中。

话虽如此,我建议使用TTimerTAction(List).OnUpdate事件处理程序来执行Button更新,而不是使用TApplication(Events).OnIdle。只要主UI消息循环完成处理来自主消息队列的消息并且空闲等待新消息到达,就会触发这些事件。当您开始处理需要更新的多个表单时,您可以为每个表单提供自己的TAction(List)TApplicationEvents

我还建议定义一个Enum来表示每个按钮,然后将BtnToDisable变量更改为这些枚举值的Set。这样,您可以禁用所需的任何按钮组合。将这些枚举值分配给每个Button的Tag属性,或使用Dictionary或类助手,或任何其他想要将Enum值与Button对象关联的方法。然后,当需要更新时,您可以简单地遍历按钮,如果给定的按钮的关联枚举值在Set中,则禁用该按钮,否则启用它。无需检查Name属性。

最后,我建议将一个Form存储在一个数组或T(Object)List中,然后你可以遍历,而不是每次循环遍历Form的Controls[]属性。