2016-10-18 4 views
0

Я пытаюсь создать (сначала) простой компонент FMX. Цель состоит в том, чтобы иметь ярлык внутри компонента и когда я нажимаю метку, чтобы ответить на его внутреннее событие onclick.Delphi Visual FMX Component

const 
    _MS_Color_Transparent_Buttons = claWhite; 
    _MS_Color_Light_Background  = claWhite; 
    _MS_Color_Dark_Background  = $FF1F2222; 
    _MS_Color_Medium_Dark_Background = $FF3D454C; 
    _MS_Color_Active_Selection  = $FF0281FD; 
    _MS_Color_Separation_Lines  = $FFE1E0E0; 

type 
    TPosItemLayout = class(TLayout) 
    private 
    { Private declarations } 
    protected 
    { Protected declarations } 
    LayMarker  : TLayout; 
    rectMarker  : TRectangle; 
    labelDescription : TLabel; 

    procedure ToggleComponent(Sender : TObject); 
    public 
    { Public declarations } 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy;     override; 
    published 
    { Published declarations } 
    end; 

constructor TPosItemLayout.Create(AOwner: TComponent); 
begin 
    inherited; 
    Self.ClipChildren := True; 
    Self.Parent  := AOwner as TFmxObject; 
    Self.Position.X := 0; 
    Self.Height  := 153; 
    Self.HitTest  := True; 

    LayMarker   := TLayout.Create(Self); 
    LayMarker.Parent  := Self; 
    LayMarker.Position.X := 0; 
    LayMarker.Position.Y := 0; 
    LayMarker.Height  := 153; 
    LayMarker.Width  := 3; 
    LayMarker.Align  := TAlignLayout.Left; 
    LayMarker.HitTest := True; 

//rectMarker 
    rectMarker    := TRectangle.Create(LayMarker); 
    rectMarker.Parent  := LayMarker; 
    rectMarker.Position.X := 0; 
    rectMarker.Position.Y := 0; 
    rectMarker.Height  := 153; 
    rectMarker.Width  := 3; 
    rectMarker.Fill.Color := _MS_Color_Active_Selection; 
    rectMarker.Fill.Kind := TBrushKind.Solid; 
    rectMarker.Stroke.Color := _MS_Color_Active_Selection; 
    rectMarker.Stroke.Kind := TBrushKind.None; 
    rectMarker.Align  := TAlignLayout.Client; 
    rectMarker.HitTest  := True; 

//lbFirstDecription - Parent LayDescription 
    labelDescription       := TLabel.Create(Self); 
    labelDescription.Parent     := Self; 
    labelDescription.Position.Y    := 8; 
    labelDescription.Height     := 23; 
    labelDescription.Align     := TAlignLayout.Horizontal; 
    labelDescription.StyledSettings   := labelDescription.StyledSettings - [TStyledSetting.FontColor, TStyledSetting.Size]; 
    labelDescription.FontColor    := claBlack; 
    labelDescription.TextSettings.Font.Size := 16; 
    labelDescription.TextSettings.HorzAlign := TTextAlign.Leading; 
    labelDescription.TextSettings.VertAlign := TTextAlign.Center; 
    labelDescription.Text     := 'Description'; 
    labelDescription.WordWrap    := False; 
    labelDescription.HitTest     := True; 
    labelDescription.OnClick     := ToggleComponent; 
end; 

destructor TPosItemLayout.Destroy; 
begin 

    inherited; 
end; 

procedure TPosItemLayout.ToggleComponent(Sender: TObject); 
begin 
    showmessage('toggle'); 
end; 

В моем тестовом приложении я нажимаю на метку, но ничего не происходит.

Я стараюсь играть вокруг hittest, но ничего.

что я пропустил?

Как сделать, чтобы это сработало?

EDIT 1 Я изменил код. OnClick на исходный код скрыт :( следующий код действует semibizar.

type 
    TPosItemLayout = class(TLayout) 
    private 
    { Private declarations } 
    protected 
    { Protected declarations } 
    imgDelete : TButton; 

    procedure ToggleComponent(Sender : TObject); 
    public 
    { Public declarations } 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy;     override; 
    published 
    { Published declarations } 
    property btnDelete : TButton read imgDelete; 
    end; 

procedure Register; 

implementation 

procedure Register; 
begin 
    RegisterComponents('Samples', [TPosItemLayout]); 
end; 

{ TPosItemLayout } 

constructor TPosItemLayout.Create(AOwner: TComponent); 
var ImgStream : TResourceStream; 
begin 
    inherited; 
    Self.ClipChildren := True; 
    Self.Position.X := 0; 
    Self.Height  := 153; 
    Self.Width  := 400; 

    imgDelete    := TButton.Create(Self); 
    imgDelete.Parent   := Self; 
    imgDelete.Width   := 60; 
    imgDelete.Height   := 24; 
    imgDelete.HitTest  := True; 
    imgDelete.Align   := TAlignLayout.Right; 
    imgDelete.Text   := 'E'; 
    imgDelete.OnClick  := ToggleComponent; 
end; 

destructor TPosItemLayout.Destroy; 
begin 

    inherited; 
end; 

procedure TPosItemLayout.ToggleComponent(Sender: TObject); 
begin 
    imgDelete.Text := 'Click'; 
end; 

во время разработки его создания кнопки и выравнивания по правому краю , но во время выполнения 2 кнопки являются упаковали .. один реагировать на кнопку и делать то, что намерены делать .. другой doesent ничего не делать.

как отслеживать эту проблему?

это messup создается IDE. Если я изменить текст на кнопке и закрыть/открыть проецировать другую кнопку. изменить текст на новой кнопке закрыть/открыть другой. на.

+0

Несомненно, вы не должны устанавливать родительский элемент управления в конструкторе. Это делает потоковая структура. –

+0

Я не знаю точно, но я был бы обеспокоен тем, что rectMarker может проглотить щелчки мыши. Я постараюсь либо сделать родительский знак labelDescription прямым, или установить HitTest для rectMarker в False. – Dsm

+0

Я более чем уверен, что мне нужно установить родителя. «Внутренний» компонент не отображается, если я этого не делаю. –

ответ

1

Это потому, что процесс потоковой передачи также создает кнопку. Необходимо отметить кнопку (и любой другой компонент, который вы собираетесь создать) с сохраненной FALSE атрибутом, как это:

property btnDelete : TButton read imgDelete; stored FALSE; 

Это остановит кнопку, сохраненные (и, следовательно, RELOADED). Но я не думаю, что это связано с вашей первоначальной проблемой (хотя может показаться, что это так). Пожалуйста, см. Мой предыдущий комментарий для того, что я думаю.

+0

Я смущен вопросами, поскольку вы, кажется, задаете две разные вещи. Для вашего первоначального вопроса: 1. Не уверен, что вам нужны дети клипа. 2. Как говорят люди, вам не нужно назначение self.parent и 3. (Чтобы ответить на ваш вопрос), hittest вашего компонента является истинным, а это означает, что ярлык никогда не получает никаких событий кликов. Asa –

2

Похож на SetSubComponent Функция, известная из VCL, не работает для FMX. Как показано в упомянутой дублированной настройке imgDelete.Stored := false - это путь. Кроме того, SetSubComponent не играет хорошо с установкой Stored = false.

+0

не работает :( –

+0

Я считаю, что это работает. Это всегда было ответом каждый раз, когда вопрос был задан раньше. –

+0

@DavidHeffernan, на самом деле это не сработает! Кажется, функция SubComponent полностью повреждена в FMX. –