AddInvoker to RadButtonElement

3 posts, 1 answers
  1. Srikanth
    Srikanth avatar
    1 posts
    Member since:
    Mar 2009

    Posted 07 Aug 2009 Link to this post

    When attempting to associate the Click event of the radButtonElement of radToolStrip, Application throws error

    "Index (zero-based) must be greater than or equal to zero and less than the size of the argument list".

    I have tried
    RadButtonElement radButtonElement = new RadButtonElement("Test");
    WorkItem.Commands"MyCommandName".AddInvoker(radButtonElement, "Click");

    with a regular ToolMenuStrip, however, i do not run into this problem. Any ideas?

    Thanks in advance.
  2. Answer
    Robert
    Robert avatar
    82 posts
    Member since:
    Jun 2009

    Posted 08 Aug 2009 Link to this post

    Hey Srikanth,

    I actually just ran into this exact problem. Here is how I solved it.

    Inside of the Telerik.CAB.WinForms project, I created an Command Adapter for the RadButtonElement. Here is the code:

    Telerik.CAB.WinForms/Commands/RadButtonElementCommandAdapter.cs
    using System; 
    using System.Collections.Generic; 
    using System.Text; 
    using Microsoft.Practices.CompositeUI.Commands; 
    using Telerik.WinControls; 
    using Telerik.WinControls.UI; 
     
    namespace Telerik.CAB.WinForms.Commands 
        class RadButtonElementCommandAdapter : EventCommandAdapter<RadButtonElement> 
        { 
            /// <summary> 
            /// Initializes a new instance of the <see cref="RadButtonElementCommandAdapter"/> class. 
            /// </summary> 
            public RadButtonElementCommandAdapter() 
                : base() 
            { 
            } 
     
            /// <summary> 
            /// Initializes a command adapter with the specified <see cref="RadButtonElement"/>. 
            /// </summary> 
            /// <param name="menuItem">The RadButtonElement instance.</param> 
            /// <param name="eventName">The name of the event.</param> 
            public RadButtonElementCommandAdapter(RadButtonElement buttonElement, string eventName) 
                : base(buttonElement, eventName) 
            { 
            } 
     
            protected override void OnCommandChanged(Command command) 
            { 
                base.OnCommandChanged(command); 
     
                foreach (RadButtonElement buttonElement in this.Invokers.Keys) 
                { 
                    if (command.Status != CommandStatus.Unavailable) 
                    { 
                        buttonElement.Visibility = Telerik.WinControls.ElementVisibility.Visible; 
                        buttonElement.Enabled = (command.Status == CommandStatus.Enabled); 
                    } 
                    else 
                    { 
                        buttonElement.Visibility = Telerik.WinControls.ElementVisibility.Collapsed; 
                    } 
                } 
            } 
        } 

    Inside of Telerik.CAB.WinForms/Application/RadWindowsFormsApplication.cs I made sure to register this new adapter type.

            protected override void AfterShellCreated() 
            { 
                base.AfterShellCreated(); 
     
                //Registers Command Adapters. 
                ICommandAdapterMapService mapService = this.RootWorkItem.Services.Get<ICommandAdapterMapService>(); 
                mapService.Register(typeof(RadMenuItem), typeof(RadMenuItemCommandAdapter)); 
                mapService.Register(typeof(RadTreeNode), typeof(RadTreeNodeCommandAdapter)); 
                mapService.Register(typeof(RadButtonElement), typeof(RadButtonElementCommandAdapter)); 
     
                // Registers UIElement Adapter Factories. 
                IUIElementAdapterFactoryCatalog catalog = this.RootWorkItem.Services.Get<IUIElementAdapterFactoryCatalog>(); 
                catalog.RegisterFactory(new RadMenuUIAdapterFactory()); 
                catalog.RegisterFactory(new RadToolStripAdapterFactory()); 
                catalog.RegisterFactory(new RadTreeViewUIAdapterFactory()); 
                catalog.RegisterFactory(new RadPanelBarUIAdapterFactory()); 
            } 

    After doing this, my commands started registering properly. Here is how I did that, just in case you need it.
                RadButtonElement buttonElement = new RadButtonElement("Add Asset"); 
                RadToolStripItem toolStripItem = new RadToolStripItem(); 
                toolStripItem.Items.AddRange(new RadItem[] { buttonElement }); 
                this.WorkItem.Commands[CommandNames.AddAsset].AddInvoker(buttonElement, "Click"); 
                this.WorkItem.UIExtensionSites[UIExtensionSiteNames.MainToolbar].Add<RadToolStripItem>(toolStripItem); 

    The only problem with this approach is that I will have to create command adapters for each of the element types supported in the toolbar. However, this should be a good workaround until one of us discovers a better way.

    - Robert


  3. UI for WinForms is Visual Studio 2017 Ready
  4. Jordan
    Admin
    Jordan avatar
    547 posts

    Posted 11 Aug 2009 Link to this post

    Hello Shoerob,

    You can create a command adapter for the base class, and create specific command adapters only when you have to handle some cases specific for an invoker. I just tried this RadElement command adapter, and it works for both RadMenuItems and RadButtonElements:

    public class RadElementCommandAdapter : EventCommandAdapter<RadElement> 
        { 
            public RadElementCommandAdapter() 
                : base() 
            { 
     
            } 
     
            public RadElementCommandAdapter(RadElement element, string eventName) 
                : base(element, eventName) 
            { 
     
            } 
     
            protected override void OnCommandChanged(Command command) 
            { 
                base.OnCommandChanged(command); 
     
                foreach (RadElement element in this.Invokers.Keys) 
                { 
                    if (command.Status != CommandStatus.Unavailable) 
                    { 
                        element.Visibility = Telerik.WinControls.ElementVisibility.Visible; 
                        element.Enabled = (command.Status == CommandStatus.Enabled); 
                    } 
                    else 
                    { 
                        element.Visibility = Telerik.WinControls.ElementVisibility.Collapsed; 
                    } 
                } 
            } 
        } 

    And here is the registration part:

     protected override void AfterShellCreated() 
            { 
                base.AfterShellCreated(); 
     
                //Registers Command Adapters. 
                ICommandAdapterMapService mapService = this.RootWorkItem.Services.Get<ICommandAdapterMapService>(); 
                //mapService.Register(typeof(RadMenuItem), typeof(RadMenuItemCommandAdapter)); 
                mapService.Register(typeof(RadTreeNode), typeof(RadTreeNodeCommandAdapter)); 
                mapService.Register(typeof(RadElement), typeof(RadElementCommandAdapter)); 
     
                // Registers UIElement Adapter Factories. 
                IUIElementAdapterFactoryCatalog catalog = this.RootWorkItem.Services.Get<IUIElementAdapterFactoryCatalog>(); 
                catalog.RegisterFactory(new RadMenuUIAdapterFactory()); 
                catalog.RegisterFactory(new RadToolStripAdapterFactory()); 
                catalog.RegisterFactory(new RadTreeViewUIAdapterFactory()); 
                catalog.RegisterFactory(new RadPanelBarUIAdapterFactory()); 
            } 

    Also, if you do not want to change the Telerik.CAB.WinForms assembly, you can retrieve the ICommandAdapterMapService after your application loads and register any custom command adapters there.

    All the best,
    Jordan
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
Back to Top