Change Tcontrol Enabled activates click event alone

Asked

Viewed 169 times

0

Fala galera,

By changing the (Tbutton) button to disabled within an event, it triggers another event.

procedure TFormulario.OnButtonExecutarOperacaoClick(Sender: TObject);
begin
  //...
  //aqui está o problema
  //a função abaixo é sincrona assim ele trava nesta linha porque chamou o evento denovo
  ButtonCancelar.Enabled:=true;//.Visible também tem o mesmo comportamento

  FuncaoQueNaoChamaPorCausaDesteProblema();
end;

Without this:

Buttoncancelar.Enabled:=true

works normally.

EDIT 1: control.inc

procedure TControl.SetEnabled(Value: Boolean);  
begin
  if FEnabled <> Value
  then begin
    EnabledChanging; //aqui chama o evento do OnButtonExecutarOperacaoClick
    FEnabled := Value;
    Perform(CM_ENABLEDCHANGED, 0, 0);
    EnabledChanged;
  end;
end;

EDIT 2 I found that only happens when the button starts with enable or Visible false. Now the resolution still have no idea

EDIT 3

procedure TControl.EnabledChanging;
begin
  DoCallNotifyHandler(chtOnEnabledChanging);
end;

procedure TControl.DoCallNotifyHandler(HandlerType: TControlHandlerType);
begin
  FControlHandlers[HandlerType].CallNotifyEvents(Self);
end;

EDIT 4

Doing some tests, if I duplicate the button and run one or the other, the form only disables the button that trigger the event, so if I have put-IT and the boot-B and tighten the put-IT only it will be disabled, even if the function disables both.

  • It takes this line, executes the event I called (in case the Operation click) and even proceeds but practically it calls 2 events

  • Code the two functions(EnabledChanging and EnabledChanged) also, I looked here in class TControl in the delphi 7 and there are no such two calls.

  • So, I didn’t put any event on these guys, I’ll edit and put the codes

  • And the EnabledChanged?

  • falls in the same...

2 answers

2

This is not the default behavior. Possibly, your code is making some recursive call. In this case, you can temporarily disable the event Handler:

procedure TFormulario.OnButtonExecutarOperacaoClick(Sender: TObject); begin ButtonCancelar.OnClick := nil; //verificar exatamente qual seria o evento recursivo try ButtonCancelar.Enabled := true; finally ButtonCancelar.OnClick := ButtonCancelarClick; end; FuncaoQueNaoChamaPorCausaDesteProblema(); end;

  • I put a little more information, I did what you commented but still he called again. The worst I created this button from scratch.

0


I decided using Ttask.Run, after a while I discovered that it had an async function within the Onclick, then at the time of calling the "Funcaoquenaochamaporcausadesteproblema()" inside it was like this

procedure TForm1.FuncaoQueNaoChamaPorCausaDesteProblema();
begin
 TTask.Run(procedure
  begin
    //...

    DesabilitarBotoes();
  end;
end;

procedure TForm1.DesabilitarBotoes();
begin
  TThread.Synchronize(nil, procedure
  begin
    //...
    ButtonCancelarOperacao.Enabled:= false;
  end);
end;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.