TLocalizedComboBox 不调用 OnDrawItem

问题描述

我正在尝试基于 TComboBox 类实现自定义控件。下面的代码可以编译,但从未调用 OnDrawItem (MyDrawItem)。我做错了什么?

unit TLocalizedComboBox_unit;

interface

uses
  System.SysUtils,System.Classes,Vcl.Controls,Vcl.StdCtrls,System.Types;

type
  TLocalizedComboBox = class(TComboBox)
  private
    { Private declarations }

  protected
    { Protected declarations }

  published
    { Published declarations }

  public
    { Public declarations }
     constructor Create(AOwner: TComponent); override;
     procedure MyDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
end;

procedure Register;

implementation
constructor TLocalizedComboBox.Create(AOwner: TComponent);
begin
     Style := csOwnerDrawFixed;
     OnDrawItem := Self.MyDrawItem;

     inherited Create(AOwner);
end;

procedure TLocalizedComboBox.MyDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
   Canvas.TextRect(Rect,Rect.Left,Rect.Top,Items.Names[Index]);
end;

procedure Register;
begin
  RegisterComponents('MyProjectsComponents',[TLocalizedComboBox]);

end;

end.

解决方法

我在下面的代码中解决了大部分问题。还有一些事情不是我想要的。

  • 代码'inherited Style := csOwnerDrawFixed'仅在设计器中没有设置不同的样式时才有效。我必须在设计器中将该属性设置为 csOwnerDrawFixed 或保留默认的“csDropDown”。 (顺便说一句,这就是 DrawItem 方法从未被调用的原因)。
  • 颜色与 csDropDownList ComboBoxes 不同,如下图所示。第三个是我从下面的代码中实现的。

enter image description here

unit TLocalizedComboBox_unit;

interface

uses
  System.SysUtils,System.Classes,Vcl.Controls,Vcl.StdCtrls,System.Types,Vcl.Forms,TLanguagesManager_6,_LanguageManagerConstants;

type
  TLocalizedComboBox = class(TComboBox)
  private
    function GetForm(control: TControl) : TForm;

  published
     procedure DrawItem(Index: Integer; Rect: TRect;  State: TOwnerDrawState); override;

  public
     constructor Create(AOwner: TComponent); override;

end;

procedure Register;

implementation
constructor TLocalizedComboBox.Create(AOwner: TComponent);
begin
     inherited;

     inherited Style := csOwnerDrawFixed;
end;

// Custom draw routine for the item. The displayed text is translated
procedure TLocalizedComboBox.DrawItem(Index: Integer; Rect: TRect;  State: TOwnerDrawState);
var
   itemToDisplay: string;
   translation  : string;
   form         : TForm;
   formName     : string;
begin
   itemToDisplay := Items[Index];
   translation   := itemToDisplay;

   if Length(itemToDisplay) > 0 then
   begin
      form          := GetForm(Self);

      if form <> nil then formName := form.Name + '.' else formName := '';
      
      translation := TLanguagesManager.GetSingleton.GetText(formName + Name + '.' + itemToDisplay,itemToDisplay);
   end;
   
   Canvas.TextRect(Rect,Rect.Left + 2,Rect.Top,translation);
end;

// Find the Form this control is on
function TLocalizedComboBox.GetForm(control: TControl) : TForm;
var
   form: TControl;
begin
     form := control.Parent;

     while form <> nil do
     begin
          if form is TForm then
          begin
              Result := form as TForm;
              form := nil;
          end
          else
              form := form.Parent;
     end;
end;

procedure Register;
begin
  RegisterComponents('MyProjectsComponents',[TLocalizedComboBox]);

end;

end.