Incus J 10 Posted April 29, 2022 I'd like to change the icon image on a tab in a TTabControl whenever that tab becomes active. So the icon acts a bit like a highlight for the currently selected tab. At the moment I have an ImageList assigned to the TTabControl Images property - and this contains two icons (one for Inactive, one for Active). I can use the OnGetImageIndex event to set the appropriate image for each tab - and this works initially. The currently active tab displays one image, and all inactive tabs display the other image. So far so good. Unfortunately OnGetImageIndex seems to fire once per tab only, when the TTabControl first loads up (in TTabControl.Loaded -> UpdateTabImages) - it never fires again (?) - so this mechanism doesn't allow a tab's image index to be changed later, say in response to a different tab becoming active. Could I somehow call the protected UpdateTabImages procedure manually, in response to a different tab being clicked and becoming active? Share this post Link to post
David Hoyle 68 Posted April 29, 2022 What about change the icon indexes in the OnChange event? Share this post Link to post
Incus J 10 Posted April 29, 2022 Maybe - I'm not sure how though (it's a TTabControl rather than a TPageControl - so there's no icon index property for each tab). Share this post Link to post
David Hoyle 68 Posted April 29, 2022 How are you setting the icons in the first place? Share this post Link to post
Incus J 10 Posted April 29, 2022 Well the two icons are in an ImageList assigned to the control. OnGetImageIndex sets the desired icon like this: procedure TForm1.TabControl1GetImageIndex(Sender: TObject; TabIndex: Integer; var ImageIndex: Integer); begin if TabControl1.TabIndex=TabIndex then ImageIndex:=1 else ImageIndex:=0; end; So if the tab is currently active it gets image 1, otherwise image 0. Which is great - it works. But only once at start up. I can't figure out how to assign a different icon index later. Share this post Link to post
Uwe Raabe 2057 Posted April 29, 2022 You can use a local class helper to access the protected method: type TTabControlHelper = class helper for TTabControl procedure UpdateTabImages; end; procedure TTabControlHelper.UpdateTabImages; begin inherited UpdateTabImages; end; 1 Share this post Link to post
Incus J 10 Posted April 29, 2022 A local class helper did the trick - perfect - thank you! Now I just call UpdateTabImages in my OnChange event handler. Share this post Link to post
Remy Lebeau 1398 Posted May 1, 2022 On 4/29/2022 at 5:40 AM, Uwe Raabe said: You can use a local class helper to access the protected method I generally prefer to use a local accessor class instead: type TTabControlAccess = class(TTabControl) end; TTabControlAccess(TabControl1).UpdateTabImages; 1 Share this post Link to post
Renate Schaaf 64 Posted May 1, 2022 1 hour ago, Remy Lebeau said: I generally prefer to use a local accessor class instead: What's the advantage? When do you use a class helper and when do you use a local accessor class, to me they both seem to serve the same purpose. Share this post Link to post
Remy Lebeau 1398 Posted May 1, 2022 3 hours ago, Renate Schaaf said: What's the advantage? When do you use a class helper and when do you use a local accessor class, to me they both seem to serve the same purpose. Personally, I only ever use class helpers when adding new methods/properties to an existing class whose interface can't otherwise be changed yet. That kind of usage is what class helpers were originally intended for. Share this post Link to post