This is a migrated thread and some comments may be shown as answers.

AddInvoker to RadButtonElement

2 Answers 116 Views
CAB Enabling Kit
This is a migrated thread and some comments may be shown as answers.
Srikanth
Top achievements
Rank 1
Srikanth asked on 07 Aug 2009, 05:59 PM
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 Answers, 1 is accepted

Sort by
0
Accepted
Robert
Top achievements
Rank 1
answered on 08 Aug 2009, 11:37 PM
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


0
Jordan
Telerik team
answered on 11 Aug 2009, 08:44 AM
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.
Tags
CAB Enabling Kit
Asked by
Srikanth
Top achievements
Rank 1
Answers by
Robert
Top achievements
Rank 1
Jordan
Telerik team
Share this question
or