TLocalizedComboBox не вызывает OnDrawItem

#custom-controls #delphi-10.4-sydney

#пользовательские элементы управления #delphi-10.4-сидней

Вопрос:

Я пытаюсь реализовать пользовательский элемент управления на основе класса 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.
 

Ответ №1:

Я решил большую часть этого в приведенном ниже коде. Есть еще несколько вещей, которые не так, как мне бы хотелось.

  • Код ‘унаследованный стиль := csOwnerDrawFixed’ работает только тогда, когда в конструкторе не задан другой стиль. Я должен установить для этого свойства значение csOwnerDrawFixed в конструкторе или оставить значение по умолчанию ‘csDropDown’. (b.t.w. вот почему метод DrawItem никогда не вызывался).
  • Цвет отличается от выпадающих списков csDropDownList, как вы можете видеть на изображении ниже. Третья — это моя реализация из приведенного ниже кода.

введите описание изображения здесь

 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.
 

Комментарии:

1. Цвета по умолчанию для cDropDownList (первые два) и cOwnerDrawFixed и включены в стандартный элемент управления TComboBox. Могу ли я изменить это поведение?