'"Control has no parent" in Create ComboBox
In this code :
unit MSEC;
interface
uses
Winapi.Windows, Vcl.Dialogs, Vcl.ExtCtrls, System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls;
type
TMSEC = class(TWinControl)
private
FOpr :TComboBox;
public
constructor Create(AOwner: TComponent); override;
end;
implementation
const
DEF_OPERATIONS :array[0..3] of Char = ('+', '-', '*', '/');
constructor TMSEC.Create(AOwner: TComponent);
var i :Integer;
begin
inherited;
FOpr:= TComboBox.Create(Self);
with FOpr do begin
Parent:= Self;
Align:= alLeft;
Width:= DEF_OPERATIONS_WIDTH;
Style:= csDropDownList;
//error in next lines :
Items.Clear;
for i := Low(DEF_OPERATIONS) to High(DEF_OPERATIONS) do Items.Add(DEF_OPERATIONS[i]);
ItemIndex:= 0;
end;
end;
end.
When I change ComboBox items, the program breaks with the message :
'Control' has no parent.
How can I fix this error or initialize ComboBox items in another way?
Solution 1:[1]
Remy explained the problem well, but for a more general solution, you could create a descendant of TComboBox, for example:
type
TComboBoxSafe = class(TComboBox)
strict private
FSafeItemIndex: Integer;
FSafeItems: TArray<string>;
function GetSafeItemIndex: Integer;
function GetSafeItems: TArray<string>;
procedure SetSafeItemIndex(const AValue: Integer);
procedure SetSafeItems(const AValue: TArray<string>);
strict protected
procedure CreateWnd; override;
procedure DestroyWnd; override;
public
constructor Create(AOwner: TComponent); override;
property SafeItemIndex: Integer read GetSafeItemIndex write SetSafeItemIndex;
property SafeItems: TArray<string> read GetSafeItems write SetSafeItems;
end;
{ TComboBoxSafe }
constructor TComboBoxSafe.Create(AOwner: TComponent);
begin
inherited;
FSafeItemIndex := -1;
end;
procedure TComboBoxSafe.CreateWnd;
var
LOnChange: TNotifyEvent;
begin
inherited;
LOnChange := OnChange;
OnChange := nil;
try
Items.Text := string.Join(sLineBreak, FSafeItems);
ItemIndex := FSafeItemIndex;
finally
OnChange := LOnChange;
end;
end;
procedure TComboBoxSafe.DestroyWnd;
begin
FSafeItemIndex := ItemIndex;
FSafeItems := Items.ToStringArray;
inherited;
end;
function TComboBoxSafe.GetSafeItemIndex: Integer;
begin
if WindowHandle <> 0 then
Result := ItemIndex
else
Result := FSafeItemIndex;
end;
function TComboBoxSafe.GetSafeItems: TArray<string>;
begin
if WindowHandle <> 0 then
Result := Items.ToStringArray
else
Result := FSafeItems;
end;
procedure TComboBoxSafe.SetSafeItemIndex(const AValue: Integer);
begin
if WindowHandle <> 0 then
ItemIndex := AValue
else
FSafeItemIndex := AValue;
end;
procedure TComboBoxSafe.SetSafeItems(const AValue: TArray<string>);
begin
if WindowHandle <> 0 then
Items.Text := string.Join(sLineBreak, AValue)
else
FSafeItems := AValue;
end;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | vfbb |
