【问题标题】:How to draw a colored border around Edit field using TShape?如何使用 TShape 在编辑字段周围绘制彩色边框?
【发布时间】:2014-02-10 23:55:25
【问题描述】:

我尝试使用 TShape 在 TEdit 字段周围绘制彩色边框。我定义了以下组件:

type TGEdit = class(TEdit)
  private
    m_shape : TShape;
  protected
    procedure setBorderColor( brd_col : TColor );
    procedure setBorderWidth( brd_wid : integer );
  public
    constructor create(AOwner : TComponent); override;
    destructor  destroy(); override;
  published
    property borderColor : TColor read m_border_color write setBorderColor default clBlack;
    property borderWidth : integer read m_border_width write setBorderWidth default 1;
end;

在构造函数中定义一个 TShape 对象。

constructor TGEdit.create(AOwner : TComponent);
begin
  inherited;
  Self.BorderStyle:= bsNone;
  m_border_color  := clBlack;
  m_border_width  := 1;
  m_shape         := TShape.Create(AOwner);
  m_shape.Parent  := Self.Parent;
  m_shape.Shape   := stRectangle;
  m_shape.Width   := Self.Width+2*m_border_width;
  m_shape.Height  := Self.Height+2*m_border_width;
  m_shape.Left    := Self.Left-m_border_width;
  m_shape.Top     := self.Top-m_border_width;
  m_shape.Brush.Style := bsClear;
  m_shape.Pen.Color   := m_border_color;
  m_shape.Pen.Style   := psSolid;
end;

destructor TGNumberEdit.destroy();
begin
  m_shape.Free();
  inherited;
end;

定义一个改变边框颜色和宽度的程序

procedure TGEdit.setBorderColor( brd_col : TColor );
begin
  if m_border_color = brd_col then
    exit;
  m_border_color    := brd_col;
  m_shape.Pen.Color := m_border_color;
end;

procedure TGEdit.setBorderWidth( brd_wid : integer );
begin
  if (m_border_width = brd_wid) or (brd_wid < 0) then
    exit;
  m_border_width    := brd_wid;
  m_shape.Pen.Width := m_border_width;
end;

但是当我将组件放在表单上时,不会绘制形状。我的代码哪里出错了?

【问题讨论】:

    标签: delphi


    【解决方案1】:

    TShape 是一个TGraphicControl 派生控件,因此除了它自己的Parent 之外,它永远不能出现在TWinControl 派生控件之上。

    您的TGEdit 构造函数中有错误。 Self.Parent 在构造函数中为 nil,因此您将 nil Parent 分配给 TShape,因此它将永远不可见。

    如果您希望TShape 与您的TGEdit 具有相同的Parent,则需要覆盖虚拟SetParent() 方法,该方法在构造完成后调用。您还必须覆盖虚拟的SetBounds() 方法,以确保您的TShape 在您的TGEdit 移动时移动,例如:

    type
      TGEdit = class(TEdit)
      ...
      protected
        ...
        procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
        procedure SetParent(AParent: TWinControl); override;
        ...
      end;
    
    procedure TGEdit.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
    begin
      inherited;
      if m_shape <> nil then
        m_shape.SetBounds(Self.Left - m_border_width, Self.Top - m_border_width, Self.Width + (2*m_border_width), Self.Height + (2*m_border_width));
    end;
    
    procedure TGEdit.SetParent(AParent: TWinControl);
    begin
      inherited;
      if m_shape <> nil then
        m_shape.Parent := Self.Parent;
    end;
    

    现在,说了这么多,还有一个替代解决方案 - 从TCustomPanel 派生您的组件,并让它在其自身之上创建一个TEdit。您可以根据需要设置面板​​的颜色、边框等。

    【讨论】:

    • 感谢您的回答,方法有效!但是当 TEdit 没有边框时,它里面的文本的垂直对齐很丑!如何纠正文本垂直位置? (这也涉及您关于使用 TPanel 的建议。)
    • 也没有必要在析构函数中销毁 TShape。
    • 边框宽度(TShape的宽度)没有改变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    相关资源
    最近更新 更多