none
Control.Tag vs Control.ID Usage

    Question

  • What is the better way to do this and if someone could give me a 2 sentence explanatino of why i would appreciate it as well. Im primarily using this with menu items and due to using multiple languages with my application, I have decided to use the tag element for the control to parse through which actual item was selected.

     

    private MenuItem foo1 = new MenuItem();
    
    private MenuItem foo2 = new MenuItem();
    
    
    
    foo1.Tag = "Hello";
    
    foo2.Tag = "GoodBye";
    
    
    
    private void itemSelected(object sender)
    
    {
    
    MenuItem sel = sender as MenuItem;
    
    switch (sel)
    
    {
    
    case "Hello":break;
    
    case "GoodBye":break
    
    }
    
    }
    
    
    
    

    • Moved by CoolDadTxMVP Wednesday, May 11, 2011 2:12 PM Winforms related (From:Visual C# General)
    Wednesday, May 11, 2011 11:39 AM

Answers

  • The Tag property on most controls allows you to attach arbitrary data to a control.  Most people use this to attach a business object to the control.  This allows you to map a control to its data more easily.  For example in a treeview displaying folders and files you might attach the DirectoryInfo or the FileInfo object associated with the node to the control so that when the user works with the node you can directly access the information without having to recreate the underlying object.  Same applies for lists.

    Buttons and other controls don't generally benefit from Tag as much but since it is defined on the base class it is provided.  For menus in WinForms some people attach command objects to the menu so they can execute the command when the menu item is clicked.  That is sort of what you're trying to do.  In general we avoid using string comparisons when possible because they aren't maintainable, easy to break and are not easily detectable at compile time.  In your case you could create a simple command object (google for many, many implementations) that has an associated delegate it calls when it is executed.  Attach the command to the menu item using the Tag property.  In your selected handler cast the Tag to your command object and then call its Execute method to execute the command without the need for any switch statement.  Refer to the Composite Application Block for a well-designed implementation of this for WinForms.

    abstract class Command
    {
       public abstract string Name { get; }
      public abstract void Execute ( );
    }

    class HelloCommand : Command
    {
       public override string Name { get { return "Hello"; } }

       public override void Execute ( )
       { MessageBox.Show("Hello"); }
    }

    class GoodbyeCommand : Command
    {
       public override string Name { get { return "Goodbye"; } }

       public override void Execute ( )
       { MessageBox.Show("Goodbye"); }
    }

    var cmds[] = { new HelloCommand(), new GoodbyeCommand ( ) };

    foreach (var cmd in cms)
    {
       var item = new MenuItem();
       item.Text = cmd.Name;
       item.Tag = cmd;
       item.ItemSelected = (o,e) =>
       {
           var target = (MenuItem)o;
           var cmd = target.Tag as Command;
           if (cmd != null) cmd.Execute();
       };
    };

    Michael Taylor - 5/11/2011
    http://msmvps.com/blogs/p3net

    Wednesday, May 11, 2011 2:11 PM

All replies

  • The Tag property on most controls allows you to attach arbitrary data to a control.  Most people use this to attach a business object to the control.  This allows you to map a control to its data more easily.  For example in a treeview displaying folders and files you might attach the DirectoryInfo or the FileInfo object associated with the node to the control so that when the user works with the node you can directly access the information without having to recreate the underlying object.  Same applies for lists.

    Buttons and other controls don't generally benefit from Tag as much but since it is defined on the base class it is provided.  For menus in WinForms some people attach command objects to the menu so they can execute the command when the menu item is clicked.  That is sort of what you're trying to do.  In general we avoid using string comparisons when possible because they aren't maintainable, easy to break and are not easily detectable at compile time.  In your case you could create a simple command object (google for many, many implementations) that has an associated delegate it calls when it is executed.  Attach the command to the menu item using the Tag property.  In your selected handler cast the Tag to your command object and then call its Execute method to execute the command without the need for any switch statement.  Refer to the Composite Application Block for a well-designed implementation of this for WinForms.

    abstract class Command
    {
       public abstract string Name { get; }
      public abstract void Execute ( );
    }

    class HelloCommand : Command
    {
       public override string Name { get { return "Hello"; } }

       public override void Execute ( )
       { MessageBox.Show("Hello"); }
    }

    class GoodbyeCommand : Command
    {
       public override string Name { get { return "Goodbye"; } }

       public override void Execute ( )
       { MessageBox.Show("Goodbye"); }
    }

    var cmds[] = { new HelloCommand(), new GoodbyeCommand ( ) };

    foreach (var cmd in cms)
    {
       var item = new MenuItem();
       item.Text = cmd.Name;
       item.Tag = cmd;
       item.ItemSelected = (o,e) =>
       {
           var target = (MenuItem)o;
           var cmd = target.Tag as Command;
           if (cmd != null) cmd.Execute();
       };
    };

    Michael Taylor - 5/11/2011
    http://msmvps.com/blogs/p3net

    Wednesday, May 11, 2011 2:11 PM
  • OK, sorry for being a dumb a - but what is this directive, statement, or command sequence mean:  

    item.Item Selected = (o,e) =>

    Is it some kind of inline function? How does it work. I also assume the statements in the brackets are part of it.

    Please don't beat me up :)


    Thursday, May 19, 2011 11:01 PM
  • It is a lambda expression.  You'll need to read up on lambda's on MSDN as it is a large, but critical, area.  Basically it is an inline anonymous function.

    (o,e) means it accepts 2 parameters (the compiler will figure out the types).  Everything inside the (optional) curlies is the method body.  When you talk about lambdas you get into closure rules.  Refer to MSDN here: http://msdn.microsoft.com/en-us/library/bb397687.aspx

    Michael Taylor - 5/20/2010
    http://msmvps.com/blogs/p3net

    Friday, May 20, 2011 2:09 PM