问题描述
我正在尝试基于 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 不同,如下图所示。第三个是我从下面的代码中实现的。
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.