场合:
我需要什么:
我需要能够通过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对象?
答案 0 :(得分:4)
您始终可以访问每个Form对象,即使您没有直接use
他们的单位。所有创建的TForm
个对象都存储在Forms
单元中全局Forms[]
对象的Screen
属性中。
话虽如此,我建议使用TTimer
或TAction(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[]
属性。