我写一个控件,继承自TCustomControl,
其中有几个属性:
  Open,Close,Opening,是显示图片TImage,在建立的时候,我是让大小位置一样,重叠在一起,其中一个Visible为True,另外两个都是False,但我在设计时候,三个都一起显示,另外,我改变其状态,也不会跟着一起改变(即我想让其中一个显示,另外两都隐藏),我有属性EnableOne,设置如下:
procedure FalseAll;
begin
  Open.Visible:=False;
  Close.Visible:=False;
  Opening.Visible:=False;
end;
procedure SetEnableOne(Value:Integer)
begin
 FalseAll;
  case Value of
   1:Openg.Visible:=True;
   2:Opening.Visible:=True;
   3:Close.Visible:=True;
  end;
end;
以上在设计下都不能,但在运行状态下一切OK,急求如何在设计状态下动态改变
以上只是我简单说一下,不知大家能否理解。

解决方案 »

  1.   

    首先,即使是VCL自己的控件,在设计期你对visible的改变也无法体验出来。但picter等属性的改变可以立即显示出来。观察vcl源码,你可以发现
    visible设置的放入除了FVisible := Value;之外还发送了消息,而这种显示和隐藏正式通过这种方式来实现的,fvisible属性只能算是一个标志用来记录现在的状态。
    procedure TControl.SetVisible(Value: Boolean);
    begin
      if FVisible <> Value then
      begin
        VisibleChanging;
        FVisible := Value;
        Perform(CM_VISIBLECHANGED, Ord(Value), 0);
        RequestAlign;
      end;
    end;procedure TControl.CMVisibleChanged(var Message: TMessage);
    begin
      if not (csDesigning in ComponentState) or
        (csNoDesignVisible in ControlStyle) then
        InvalidateControl(True, FVisible and (csOpaque in ControlStyle));
    end;再去看那些可以改变的,例如image的picter属性
    procedure TImage.SetPicture(Value: TPicture);
    begin
      FPicture.Assign(Value);
    end;脑子里还有些东西,不过水平不够,描述不出来了,不过基本反映了我的思路。那么如果想按照你说的实现在设计期的隐藏,可以换个思路,就是对visable的修改不是单纯意义上去修改一个标志,而是修改那些设计期可以将变动反映出来的属性,例如Parent。刚才做了一个例子,用的一个组件panel里边包容了两个edit,在修改了visable的数值后,改变他的parent属性。
    unit editPanel;interfaceuses
      SysUtils, Classes, Controls, ExtCtrls,StdCtrls;type
      teditPanel = class(TPanel)
      private
        Fedit1 : tedit;
        Fedit2 : tedit;
        procedure Setedit2visable(value: Boolean);
        function GetEdit2Visable:Boolean;  protected
        { Protected declarations }
      public
        constructor Create(AOwner: TComponent); override;
      published
        property edit1:TEdit read Fedit1;
        property edit2visable : Boolean read GetEdit2Visable write Setedit2visable stored true;
      end;procedure Register;implementationprocedure Register;
    begin
      RegisterComponents('wudi', [teditPanel]);
    end;{ teditPanel }constructor teditPanel.Create(AOwner: TComponent);
    begin
      inherited;
      Self.Width := 500;
      Self.Height := 500;
      fedit1 :=TEdit.Create(Self);
      fedit2 := TEdit.Create(Self);
      Fedit1.Parent := Self;
      Fedit2.Parent := Self;
      fedit1.Text := 'edit1';
      fedit2.Text := 'edit2';
      fedit1.Left := 100;
      fedit2.Left := 200;  fedit1.Top := 100;
      fedit2.Top := 100;
    end;
    function teditPanel.GetEdit2Visable: Boolean;
    begin
       Result := Fedit2.Visible;
    end;procedure teditPanel.Setedit2visable(value: Boolean);
    begin
       Fedit2.Visible := value;
    //这里通过改变parent属性来实现在设计期隐藏和显示子控件
       if value then Fedit2.Parent := Self
       else Fedit2.Parent := nilend;end.上述例子,winxp+d7下测试通过。
      

  2.   

    procedure TControl.CMVisibleChanged(var Message: TMessage);
    begin
      if not (csDesigning in ComponentState) or
        (csNoDesignVisible in ControlStyle) then
        InvalidateControl(True, FVisible and (csOpaque in ControlStyle));
    end;
    仔细看了一下,这里的有csDesigning in ComponentState这样一句。所以在设计时,不会执行
    InvalidateControl(True, FVisible and (csOpaque in ControlStyle));
      

  3.   

    楼上说完了,按楼上的说法,你把控件的ControlStyle加上csNoDesignVisible就ok了.
      

  4.   

    如果只是简单的想完成设计期的显示和隐藏,通过改写parent比较方便。否则的话,会比较麻烦。
      

  5.   

    呵,谢谢,
    我使用另外一种方法,使用Image,再加上几个TPicture,每个Picture,装入一个图片,动态改变Image.Picture的值
    2、楼上的也是一种好方法,感谢!
    不知还有没有更好的方法,让速度更快一些。这个控件有需要5个画面根据状态不断地显示5个图片。有两组,一组三个画面,需要根据状态变,一组两个根据状态变。所以我就把他们装入一个控件中,设置两个属性值。每个页面上需要20多个这里的控件,根据状态变,所以,有没有更好方法达到速度快,CPU占用率低。