Saurabh Rai
Saurabh Rai

Reputation: 33

Disable/Enable Control onPaint event , but Changes not reflecting

I am trying to Enable/Disable control in OnPaint event, but Changes are not getting reflected. How ever if toggle with other application changes getting reflected(using ALT+TAB)

procedure TfrmBase.FormPaint(Sender: TObject);
var 
...
...  
begin

  flg := False;
  for i := ComponentCount - 1 downto 0 do
  begin
    Temp := Components[i];

    if (Temp is TToolButton) then
    begin

            (Temp as TToolButton).Enabled := SomeFuncWhichReturnBoolean;

    end
    else if (Temp is TButton) then

          (Temp as TButton).Enabled   := SomeFuncWhichReturnBoolean ;


  end;


end;

Please suggest

Upvotes: 0

Views: 429

Answers (2)

Sir Rufo
Sir Rufo

Reputation: 19106

Generally spoken, there is a time to change the states and there is a time to paint the current states. Don't mix them up.

Each button represents an action that will happen when you press the button and this action is maybe allowed or not.

Delphi has a TActionList where you can manage actions. Each action has an OnExecute (what should happen) and an OnUpdate event. This OnUpdate event is a perfect place to enable or disable the action.

procedure TFoo.BarActionExecute(Sender:TObject);
begin
  DoBarAction();
end;

procedure TFoo.BarActionUpdate(Sedner:TObject);
begin
  (Sender as TAction).Enabled := CanDoBarAction();
end;

Just wire up all the buttons with the actions from your TActionList

Upvotes: 1

GolezTrol
GolezTrol

Reputation: 116160

OnPaint is for painting, and it's not the right moment to change states. Doing this will at best trigger another paint, or at worst it won't. So either the code doesn't work, or it works inefficiently. Moreover, Paint isn't called all the time. Even when you move the form around there is no guarantee that it will be repainted. So, as a trigger, this is a very unreliable event.

Instead, toggle the control when it it added to or removed from DisableControlList. Changing Enabled of the control should trigger a repaint, so you don't have to worry about that part.

You failed to mention what kind of list this is, but maybe it has an OnChange event you can use, or you can wrap it or inherit from it to implement the toggle without making it the responsibility of the procedure that added the control to the list. The code you now have, should be in that OnChange event.

Upvotes: 1

Related Questions