Jump to content
PeterPanettone

TButtonItem does not have a TAG property

Recommended Posts

Posted (edited)

In Delphi 10.4, TCategoryButtons.TButtonCategory.TButtonItem does not have a Tag property.

 

So I cannot write:

 

CategoryButtons1.Categories[0].Items[0].Tag := 1;

 

Is there a trick to add a Tag property to TButtonItem without rewriting the whole class?

Edited by PeterPanettone

Share this post


Link to post
22 minutes ago, Anders Melander said:

Use the TButtonItem.Data property instead - or TButtonItem.Action.Tag?

Thanks! TButtonItem.Action.Tag is the most simple and therefore the best solution.

Share this post


Link to post
16 minutes ago, PeterPanettone said:

Sometimes I wish we had a Tag1 and Tag2 property

Versatility comes at a cost.

You can use an external TDictionary<TButtonItem, WhatEver> if you need to associate additional data.

Share this post


Link to post

I have never understood why Tag would ever be used. I mean I get it for a toy program knocked up in a couple of minutes. But not for real world code. 

  • Sad 1

Share this post


Link to post
10 hours ago, David Heffernan said:

I have never understood why Tag would ever be used. I mean I get it for a toy program knocked up in a couple of minutes. But not for real world code. 

For stuffing in pointers and such... it is not appropriate, but for storing integer values that can later be used to determine appropriate action... why would that be wrong or used only in toy apps?

 

In Delphi I never used Tag in toy apps knocked up in minutes, because they were pretty simple, but in more complex ones, especially with dynamic content and multiple entry points for actions, tag is the most straight forward thing to use and maintain.

 

Also, just yesterday, I wrote a whole a lot of tag based code in native Xcode iOS application where native view also has tag property specifically used for determining which action you want to run. And there just like in Delphi you have Sender object that you can also use to determine appropriate action, but just like in Delphi code working with objects would be more convoluted and using Tag is preferred when you have to determine or change action at runtime.

 

 

Share this post


Link to post
2 hours ago, Dalija Prasnikar said:

For stuffing in pointers and such... it is not appropriate, but for storing integer values that can later be used to determine appropriate action... why would that be wrong or used only in toy apps?

 

In Delphi I never used Tag in toy apps knocked up in minutes, because they were pretty simple, but in more complex ones, especially with dynamic content and multiple entry points for actions, tag is the most straight forward thing to use and maintain.

 

Also, just yesterday, I wrote a whole a lot of tag based code in native Xcode iOS application where native view also has tag property specifically used for determining which action you want to run. And there just like in Delphi you have Sender object that you can also use to determine appropriate action, but just like in Delphi code working with objects would be more convoluted and using Tag is preferred when you have to determine or change action at runtime.

 

 

I'd far sooner use Sender in an event handler to identify the control, and then have a map to anything else.  Tag falls over as soon as you need to handle more than a single aspect.  Plus there is no type safety.

  • Sad 1

Share this post


Link to post
1 minute ago, David Heffernan said:

Tag falls over as soon as you need to handle more than a single aspect.  Plus there is no type safety.

I mostly agree; Tag is often the mark of poor workmanship. When used at design-time you have to assign magic numbers with "hidden meaning" and it can very easily become a nightmare to maintain. The same goes for the GroupIndex property.

 

For run-time though I'm not that concerned with it as long as the use is very limited. Sometimes you just want to get on with the the task at hand and using a dictionary to associate a handful of controls to some context can seem like overkill.

That said, use of Tag definitely goes against my primary rule of development: Don't be lazy

  • Sad 1

Share this post


Link to post

Isn't it common practice to store pointers to objects in the tag property? At least that's what I've learned by looking at some legacy code 😉

/sarcasm off

Share this post


Link to post
Posted (edited)
1 hour ago, David Heffernan said:

I'd far sooner use Sender in an event handler to identify the control, and then have a map to anything else.  Tag falls over as soon as you need to handle more than a single aspect.  Plus there is no type safety.

Sorry, but I don't see how

 

if Sender is FooButton then
  DoFoo
else
if Sender is BarButton then
  DoBar
....

Is preferable to

 

case TComponent(Sender).Tag of
  TAG_FOO : DoFoo;
  TAG_BAR : DoBar;
...
end;

It also gets worse if you have several Senders that perform same task - for instance, button and menu (I know that you can have actions, but actions share same caption - not always preferable, especially in non-English environments)

 

I am aware that you can also add dictionary and map actions that way, but then you need to maintain dictionary, its lifetime, mappings and on top of that you don't have spelled out logic in place where action happens - following code through dictionary is debugging nightmare.

 

Mappings are mappings... you can always use wrong mapping being it integer based or not.

 

Edited by Dalija Prasnikar
code correction
  • Like 2

Share this post


Link to post

Shouldn't that read

case TComponent(Sender).Tag of   
  TAG_FOO : DoFoo;   
  TAG_BAR : DoBar;
... 
end;

 

  • Like 1
  • Thanks 1

Share this post


Link to post

Just to make it clear, I am not dismissing using dictionary mapping where it fits better (if you don't have up front defined set of actions at call site), I am merely objecting to the notion that using integer tags is toy programming.

  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×