#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. Могу ли я изменить это поведение?