【问题标题】:How can I control the order of items in the Components array?如何控制 Components 数组中项目的顺序?
【发布时间】:2012-07-18 11:07:15
【问题描述】:

我在 Delphi 中开发了一个带有 TEdit 组件的小应用程序。
我使用这个函数来验证组件字段是否为空。

function TF_config.Validatefields:boolean;
var 
  i : integer;
begin
 for i := 0 to ComponentCount - 1 do
 begin
   if (Components[i]is TEdit) then
   begin
      if ((TEdit(Components[i]).Text) ='') then
      begin
        MessageDlg('Enter data in all the fields',mtWarning,[MBOK],0);
        TEdit(Components[i]).SetFocus;
        result := false;
        exit;
     end;             
   end;  //end for TEdit
 end;    //end component count 
 result := true;
end;

现在我必须再添加一个组件

函数检查数据是否有效的顺序是 ID->姓名->地址->电话->年龄。但我希望它是 ID->Name->Address->Age->Phone
我尝试解决它删除 Phone Edit 组件,然后在添加 Age Edit 组件后添加它。或者使用 Phone Edit 组件为 Age 并为 Phone 添加新的 Edit 组件。这对于少数组件来说更容易,但在拥有许多组件时变得乏味。 所以我想知道我们是否可以以适合我们的方式安排组件。这可能吗?

【问题讨论】:

    标签: delphi components


    【解决方案1】:

    您可以使用TabOrder 属性进行排序,使用FindNextControl 方法在控件之间移动。

    【讨论】:

    • 对。我认为假设您希望在编辑时按照在运行时遍历它们的顺序完成检查是有效的。
    【解决方案2】:

    我建议将控件放在您自己的列表/数组中,然后您可以完全控制其内容和顺序,并且可以在需要时循环遍历它。这也确保您只触摸您真正感兴趣的控件,而不是浪费时间触摸您不感兴趣的其他控件,并且它还允许 VCL 在它认为合适的时候维护其自己的内部列表的顺序。

    type
      TF_config = class(TForm)
        procedure FormCreate(Sender: TObject);
      ...
      private
        EditFields: array[0..4] of TEdit;
        function ValidateFields: Boolean; 
      ...
      end;
    
    procedure TF_config.FormCreate(Sender: TObject);
    begin
      EditFields[0] := IdEdit;
      EditFields[1] := NameEdit;
      EditFields[2] := AddressEdit;
      EditFields[3] := AgeEdit;
      EditFields[4] := PhoneEdit;
    end; 
    
    function TF_config.ValidateFields: Boolean; 
    var  
      i : integer; 
    begin 
      for i := Low(EditFields) to High(EditFields) do 
      begin 
        if EditFields[i].GetTextLen = 0 then 
        begin 
          MessageDlg('Enter data in all the fields', mtWarning, [MBOK], 0); 
          EditFields[i].SetFocus; 
          Result := False; 
          Exit; 
        end;              
      end;
      Result := True; 
    end; 
    

    更新:如果您需要验证多种类型的控件,则可以改为:

    type 
      TF_config = class(TForm) 
        procedure FormCreate(Sender: TObject); 
      ... 
      private 
        Fields: array[0..4] of TControl; 
        function ValidateFields: Boolean;  
      ... 
      end; 
    
    procedure TF_config.FormCreate(Sender: TObject); 
    begin 
      Fields[0] := ...; 
      Fields[1] := ...; 
      ...
      Fields[4] := ...; 
    end;  
    
    function TF_config.ValidateFields: Boolean;  
    var   
      i : Integer;  
      ctrl: TControl;
    begin  
      Result := True;
      for i := Low(Fields) to High(Fields) do  
      begin  
        ctrl := Fields[i];
        if ctrl is TCustomEdit then // handles both TEdit and TMemo
        begin  
          if TCustomEdit(ctrl).GetTextLen = 0 then  
          begin  
            Result := False;
            Break;
          end;               
        end;
        if ctrl is TComboBox then
        begin  
          if TComboBox(ctrl).ItemIndex = -1 then  
          begin  
            Result := False;
            Break;
          end;               
        end;
        ... and so on ...
      end;
      if not Result then
      begin
        MessageDlg('Enter data in all the fields', mtWarning, [MBOK], 0);  
        ctrl.SetFocus;  
      end;
    end; 
    

    【讨论】:

    • 不错的解决方案,但是有备注字段、组合框等会导致更多的组件数组可能会消耗更多的空间。
    • 并非如此。即使有更多类型的控件,仍然首选使用您自己的列表。而且您可以使用一个包含TControl 指针的列表,并在需要时对它们进行类型转换,就像原始代码所做的那样,但至少列表的顺序仍然是您想要的,而且您仍然不必浪费时间查看所有其他不适用于验证的控件。
    【解决方案3】:
    1. 在 IDE 中,按 Alt+F12 或右键单击表单并选择“以文本形式查看”以打开表单的资源 (.dfm)
    2. 根据需要重新排列组件(剪切和粘贴)。它们在资源中出现的顺序是它们在运行时在表单的Components 属性中列出的顺序。

    【讨论】:

    • 这是唯一的方法吗?不过感谢您的回答。
    • 您也可以重写代码以完全不依赖Components 的顺序。
    • 看来这里没有捷径可走。
    • @TOndrej:您可以右键单击表单设计器并选择“创建顺序”选项,而不是手动更改 DFM。然后,您可以使用可视列表根据需要排列控件。
    • @RemyLebeau AFAIK 创建顺序仅适用于非可视组件,不是吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 2021-05-14
    • 1970-01-01
    相关资源
    最近更新 更多