Strange Event Behavior (Controls with same tag value cause duplicate events)

  • Thread starter Thread starter Joseph Geretz
  • Start date Start date
J

Joseph Geretz

Writing an Outlook AddIn with C#. For the user interface within Outlook I'm
adding matching pairs of Toolbar buttons and Menu items. All of the buttons
and menu items are wired up to send events to the same method (aka
delegate?). I use the Tag property within this method to determine what user
action is taking place. Very simple:

When adding toolbar button:
tbButton.Click += new
Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.User_Click);

When adding Menu item:
MenuItem.Click += new
Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.User_Click);

private void User_Click(CommandBarButton cmdButton, ref bool cancel)
{
MessageBox.Show(cmdButton.Tag);
}

Right now, all I've got is a simple dialog box to show me what's going on.

Strangely enough, if I use the same Tag for a Menu item and its
corresponding Toolbar button (This makes sense for me, since for any given
action, I don't really care if the user clicked a Menu or a Toolbar button)
I get two message boxes. Why two??? Surely, the delegate method is wired up
per object instance and not tracked by the Tag of the object? But seemingly,
when I click a Menu I get the event for the menu and the corresponding event
for the corresponding toolbar button as well! And vice versa. This is very
strange.

If I change the Tags so they don't match (e.g. Find|Toolbar and Find|Menu as
opposed to simply Find and Find) then I get the expected behavior. It's easy
enough for me to do this, and then strip out the basic tag value as follows:

MessageBox.Show("Viewpoint - " +
cmdButton.Tag.Remove(cmdButton.Tag.IndexOf("|")));

However, I'm puzzled by why this should all be necessary. Can you explain
this to me?

Thanks very much for your help!

- Joseph Geretz -
 
Function as designed: the click even will fire for all controls with the
same value of the Tag property. If you don't want that, you must set the Tag
property to a unique strign for each instance of a button/menu item.
You need to use different event handlers rather than try to differentiate
the originating buttons using the Tag property.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
Hi Dmitry,

Thanks for your advice.
Function as designed: the click even will fire for all controls with the
same value of the Tag property. If you don't want that, you must set the
Tag property to a unique strign for each instance of a button/menu item.

OK, this is no problem. I've essentially done this, in order to workaround
what I observed. I'm glad to hear though, that the events are working
according to spec. BTW, can you give me a link to where this is documented?
I've always perceived the Tag property as a data bucket for developer's
convenience. It surprises me to hear that internal events are firing (or
not) based on the value in the Tag property.
You need to use different event handlers rather than try to differentiate
the originating buttons using the Tag property.

Are you saying that the way I'm wiring this up is fundamentally problematic?
Or just that I need to be careful to implement unique Tag properties in
order to facillitate this approach?

Thanks for your help,

- Joe Geretz -
 
I don't think this is documented anywhere, this is just the way things
work... :-)
What I mean is that you need to use separate event handlers for different
buttons if they are supposed to do different things:

ButtonOne.Click += new
Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.User_ButtonOneClick);
ButtonTwo.Click += new
Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.User_ButtonTwoClick);

You can of course reuse the same event handler if, for example, both the
particular menu item and the toolbar button do the same thing.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
I don't think this is documented anywhere, this is just the way things

I was discussing this phenomenon with a colleague this afternoon. I'm a
little better versed in .NET / C#, but he has a wide range of experience
with other object oriented environments. Notwithstanding that this is the
way it works, neither of us could come up with any idea of why the Tag
property (of all things) would create any linkage between objects. Can
anyone comment on why this works the way it does?
ButtonOne.Click += new
Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.User_ButtonOneClick);
ButtonTwo.Click += new
Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.User_ButtonTwoClick);

Sure, that's one way to do it. Another way is to have one event handlers
with a Case statement to dispatch a function call to the appropriate
function, depending on the object which is clicked. The advantage I see to
this latter approach is that it makes it really easy to add a whole suite of
buttons through a centralized function.

In context, the AddIn which I am writing is basically a conduit, or linkage
between Outlook and an Application which I've written. As such, most of the
AddIn is simply creating Buttons and then dispatching button clicks to my
own application, along with information about the current context within
Outlook (i.e. current Contact, Appointment or Message). As such, much of the
code within the AddIn is simply involved with creating the AddIn interface
(Menus and Toolbar Buttons) and so that's where I'm leaning toward
optimization. By centralizing and generalizing the Menu / Button creation
code, I'm developing a programmatic structure which will eventually be
data-driven, for example, by an XML file. I'll be able to add new Menus and
Buttons simply by creating new entries in an XML file. This isn't something
which could be easily accommodated if each Menu / Button needed its own
dedicated event handler.

- Joe Geretz -
 
I don't think this is documented anywhere, this is just the way things
Hmm, this is not the way it works in a universal sense at all.

Simple Windows form application; Created two buttons. Wired them up to the
same event handler, Button_Click. Gave each one the same Tag. (Code extract
below.) This works as I expect. Clicking on either button generates one, and
only one, callback to the event handler. So why the weird behavior in
Outlook? Is it *Outlook* which creates the linkage between Menu Items and
Toolbar buttons with the same Tag property? Hmm...

So, back to my AddIn project. I implemented two separate event handlers; one
for Menu Items and one for Toolbar Buttons. I went back and reset the Tags
back to their matching values. Clicked on a menu item - sure enough; two
events are fired.

So it seems clear to me that it is after all, *Outlook* which implements the
bizarre behavior by cycling through the Menu Items and Toolbar buttons and
clicking all those with matching Tag properties, every time a Menu or Button
is clicked. Now why in the world would it do something like that?

Very strange...

- Joe Geretz -

//
// button1
//
this.button1.Location = new System.Drawing.Point(91, 32);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Tag = "X";
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.Button_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(91, 61);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 1;
this.button2.Tag = "X";
this.button2.Text = "button2";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.Button_Click);
 
I don't think this is documented anywhere, this is just the way things
It is documented in various places, e.g. http://msdn2.microsoft.com/en-US/library/0batekf4.aspx:

"You must set the Tag property on your controls when you add event handlers. Office uses the Tag property to keep track of event handlers for a specific CommandBarControl. If the Tag property is blank, the events are not handled properly."

Also, without explanation, in the sample code at http://msdn2.microsoft.com/en-US/library/ms268864.aspx
Hmm, this is not the way it works in a universal sense at all.

Right, this behavior is specific to Office add-ins.

--
Sue Mosher, Outlook MVP
Author of Configuring Microsoft Outlook 2003

and Microsoft Outlook Programming - Jumpstart for
Administrators, Power Users, and Developers
 
Back
Top