自定义组件和制表符顺序 [英] Custom component and tab order

查看:64
本文介绍了自定义组件和制表符顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义组件(从 TCustomPanel 继承),由两个其他组件组成(比如说两个编辑)。使用组件时如何正确获得制表符顺序?

I have a custom component (inheriting from TCustomPanel) that consists of two other components (let's say two edits). How do I get the tab order right when using the component?

在制表符顺序设计器中,我只能访问没有焦点的组件本身,因为它是面板。在运行时发生的事情是,我可以使用Tab键来访问编辑,但是只有在组件下方的两个按钮被聚焦之后才可以访问。

In the tab order designer I can only access the component itself which cannot have focus because it is a panel. What happens at runtime is that I can access the edits using the tab key, but only after the two buttons below the component got focused.

如何更改选项卡顺序在这种情况下?

How can I change the tab order in this situation?

推荐答案

组件中这些嵌套控件的制表符顺序与表单上的制表符顺序不同您的组件所在。当您选择嵌套控件时,将在表单的选项卡顺序列表中确定组件的选项卡顺序。一旦所有选项卡顺序列表组合在一起,它们就会进入最后一个循环:

The tab order of those nested controls within your component is distinct from the tab order of the form on which your component resides. The tab order of the component in the tab order list of the form desides when you tab to the nested controls. Once all tab order lists combined, they result in the final cycle:


  • 窗体上的控件( TabOrder = 0

  • 窗体上的另一个控件( TabOrder = 1

  • 您的面板组件( TabOrder = 2

    • 编辑1( TabOrder = 0

    • 编辑2( TabOrder = 1

    • A control on the form (TabOrder=0)
    • Another control on form (TabOrder=1)
    • Your panel component (TabOrder=2)
      • Edit 1 (TabOrder=0)
      • Edit 2 (TabOrder=1)

      要设置面板​​组件设计时间的制表顺序:

      To be able to set the tab order of the panel component design time:


      • 在设计器中使用制表符顺序编辑器(右键单击组件的父级),然后在编辑器中使用箭头更改制表符顺序,或者

      • 为您的组件发布 TabOrder 属性,并将其设置在对象检查器中:

      • Use the tab order editor in the designer (right click on the parent of the component) and change the tab order with the arrows in the editor, or
      • Publish the TabOrder property for your component and set it in the object inspector:

      type 
        TMyPanel = class(TCustomPanel) 
        published 
          property TabOrder; 
        end; 
      


    • 在运行时始终可以设置组件的Tab键顺序,因为 TabOrder 属性在 TWinControl 中声明为公共。

      At runtime it is always possible to set the tab order of the component since the TabOrder property is declared public in TWinControl.


      ...因为它是一个面板而无法获得焦点。

      ... which cannot have focus because it is a panel.

      否,面板可以使焦点集中起来,但是默认情况下不会。这是通过 TabStop 属性处理的,默认情况下为 False 。您不希望 TabStop 为组件设置 True ,因为(1)面板没有指示器,它没有焦点(2)这是我所不希望的。

      No, a panel can aqcuire focus just fine, but will not by default. This is handled with the TabStop property, which is False by default. You don't want TabStop to set True for your component since (1) a panel has no indicator it has focus and (2) it is not desired (I imagine).

      更改嵌套控件的制表符顺序最好

      Changing the tab order of the nested controls is preferably done in the constructor of your component, or at runtime.

      要在设计时设置组件内嵌套控件的制表顺序,还需要做更多的工作。 我不认为您想要那样,但是由于我先前的答案(已删除)是垃圾(并被强烈投票),因此我提出了一个补偿示例。

      To be able to set the tab order of the nested controls within you component at design time requires some more work. I do not think you want that, but since my previous answer (deleted) was rubbish (and voted on, strangly) I have worked out an example as compensation.

      首先,请注意,使用设计器中的选项卡顺序编辑器设置这些编辑的选项卡顺序(在面板组件上单击鼠标右键)将更改选项卡顺序,但不会持久。那是因为这些更改没有流式传输到DFM。

      First, notice that setting the tab order of those edits with the tab order editor in the designer (right click on the panel component) will change the tab order, but it will not last. That is because those changes are not streamed to the DFM.

      要能够流式传输/保存控件的设计时更改,您需要发布它们:

      To be able to stream/save the design time changes of the controls, you need to publish them:

      type
        TMyPanel = class(TCustomPanel)
        private
          FEdit1: TEdit;
          FEdit2: TEdit;
        public
          constructor Create(AOwner: TComponent); override;
        published 
          property Edit1: TEdit read FEdit1;
          property Edit2: TEdit read FEdit2;
        end;
      
      constructor TMyPanel.Create(AOwner: TComponent);
      begin
        inherited Create(AOwner);
        FEdit1 := TEdit.Create(Self);
        FEdit1.SetBounds(10, 10, 100, 21);
        FEdit1.Name := 'Edit1';
        FEdit1.Parent := Self;
        FEdit1.SetSubComponent(True);
        FEdit2 := TEdit.Create(Self);
        FEdit2.SetBounds(10, 41, 100, 21);
        FEdit2.Name := 'Edit2';
        FEdit2.Parent := Self;
        FEdit2.SetSubComponent(True);
      end;
      

      当然,这会发布这些控件的所有属性,现在用户可以更改所需的内容。为避免这种情况,请考虑限制 TEdit 控件的发布属性:

      Of course this publishes áll properties of those controls and now users can change whatever they want. To prevent this, consider limiting the published properties of the TEdit controls:

      unit MyPanelEdit;
      
      interface
      
      uses
        DesignEditors, Unit2, DesignIntf, SysUtils, Classes, TypInfo, StdCtrls;
      
      type
        TEditProperty = class(TComponentProperty)
        private
          function FilterFunc(const ATestEditor: IProperty): Boolean;
        public
          function GetAttributes: TPropertyAttributes; override;
          procedure GetProperties(Proc: TGetPropProc); override;
        end;
      
      procedure Register;
      
      implementation
      
      procedure Register;
      begin
        RegisterPropertyEditor(TypeInfo(TEdit), TMyPanel, '', TEditProperty);
      end;
      
      { TEditProperty }
      
      function TEditProperty.FilterFunc(const ATestEditor: IProperty): Boolean;
      begin
        Result := ATestEditor.GetName = 'TabOrder';
      end;
      
      function TEditProperty.GetAttributes: TPropertyAttributes;
      begin
        Result := [paSubProperties];
      end;
      
      procedure TEditProperty.GetProperties(Proc: TGetPropProc);
      var
        LComponents: IDesignerSelections;
        LDesigner: IDesigner;
      begin
        LComponents := GetSelections;
        if LComponents <> nil then
        begin
          if not Supports(
              FindRootDesigner(LComponents[0]), IDesigner, LDesigner) then
            LDesigner := Designer;
          GetComponentProperties(LComponents, [tkInteger], LDesigner, Proc,
            FilterFunc);
        end;
      end;
      
      end.
      

      这限制了已发布的 TEdit 的属性属性仅显示 TabOrder

      This limits the properties of the published TEdit properties to show only TabOrder.

      这篇关于自定义组件和制表符顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆