Linking a Ribbon Button to a .Net Command

Linking a Ribbon Button to a .Net Command

JamesLH88
Explorer Explorer
8,788 Views
22 Replies
Message 1 of 23

Linking a Ribbon Button to a .Net Command

JamesLH88
Explorer
Explorer

Hi All,

 

I wonder if anybody can help me.

 

I have a few commands that I have created, and they work great if called via the command line.

 

[CommandMethod("MyCommand", CommandFlags.UsePickSet | CommandFlags.Redraw | CommandFlags.Modal)]
public void MyCommandFunction()
{
       // MY CODE IS HERE
}

I have also created a new ribbon tab, with panel, and RibbonButton, and assigned a CommandHandler which calls a Action (callback function). However, I can't seem to get my button to trigger 'MyCommand'.

 

RibbonCommandHandler ActionHandler = new RibbonCommandHandler();
ActionHandler.CallBack = CallBackFunction;
myButton.Id = "MyButtonID";
myButton.CommandHandler = ActionHandler;


public class RibbonCommandHandler : System.Windows.Input.ICommand
{
    public Action<String> CallBack;
    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        if (parameter is RibbonButton)
        {
            RibbonButton button = parameter as RibbonButton;
            CallBack(button.Id);
        }
    }
}


public void CallBackFunction(String message)
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
            
    switch (message)
    {
        case "MyButtonID":
            // I AM STUCK HERE .....
            break;
    }
}

 

Apologies if I have failed to explain my problem very clearly. I am not sure if I am even going around the issue the right way. But any assistance to point me in the right direction would be greatly appreciated!

 

 

Thanks,

James

 

 

 

 

 

0 Likes
Accepted solutions (2)
8,789 Views
22 Replies
Replies (22)
Message 2 of 23

ActivistInvestor
Mentor
Mentor

@JamesLH88 wrote:

Hi All,

 

I wonder if anybody can help me.

 

I have a few commands that I have created, and they work great if called via the command line.

 

[CommandMethod("MyCommand", CommandFlags.UsePickSet | CommandFlags.Redraw | CommandFlags.Modal)]
public void MyCommandFunction()
{
       // MY CODE IS HERE
}

I have also created a new ribbon tab, with panel, and RibbonButton, and assigned a CommandHandler which calls a Action (callback function). However, I can't seem to get my button to trigger 'MyCommand'.

 

RibbonCommandHandler ActionHandler = new RibbonCommandHandler();
ActionHandler.CallBack = CallBackFunction;
myButton.Id = "MyButtonID";
myButton.CommandHandler = ActionHandler;


public class RibbonCommandHandler : System.Windows.Input.ICommand
{
    public Action<String> CallBack;
    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        if (parameter is RibbonButton)
        {
            RibbonButton button = parameter as RibbonButton;
            CallBack(button.Id);
        }
    }
}


public void CallBackFunction(String message)
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
            
    switch (message)
    {
        case "MyButtonID":
            // I AM STUCK HERE .....
            break;
    }
}

 

Apologies if I have failed to explain my problem very clearly. I am not sure if I am even going around the issue the right way. But any assistance to point me in the right direction would be greatly appreciated!

 

 

Thanks,

James

 

 

 

 

 


Typically, you would set the Macro property of the RibbonCommandButton in xaml, to the name of your command (.e.g, "MYCOMMAND"), and that's it. The RibbonCommandButton takes care of the rest.

 

You don't have to implement ICommand unless you need to enable/disable the ability to use the command based on some runtime condition.

 

 

0 Likes
Message 3 of 23

norman.yuan
Mentor
Mentor
Accepted solution

I believe the OP's question is about RibbonButton (RibbonCommandItem) in Autodesk.Windows.Ribbon namespace (AdWindows.dll), where the OP dynamically creates/updates ribbon items, not RibbonCommandButton in Autodesk.AutoCAD.Ribbon namespace (AcWindows.dll).

 

To OP:

 

You can set RibbomCommandItem.CommandParameter to the custom command, and call Document.SendStringToExecution() in the command handler's Execute() method, something like:

 

myButton.CommandParameter="MyCommand"

 

Then in the command handler:

 

public void Execute(object parameter)

{

   var ribbonItem=parameter As RibbomCommandItem;

   if (ribbonItem!=null)

   {

      var doc=ApplicationDocumentManager.MdiDocument  

 

      //Make sure the command text either ends with ";", or a " "

      string cmdText=((string)ribbonItem.CommandParameter).Trim();

      if (!cmdText.EndsWith(";")) cmdText=cmdText + " ";

      

     doc.SendStringToExecite(cmdText, .....);

   }

}

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 4 of 23

ActivistInvestor
Mentor
Mentor

@norman.yuan wrote:

I believe the OP's question is about RibbonButton (RibbonCommandItem) in Autodesk.Windows.Ribbon namespace (AdWindows.dll), where the OP dynamically creates/updates ribbon items, not RibbonCommandButton in Autodesk.AutoCAD.Ribbon namespace (AcWindows.dll).

 

 


Looking at it again more closely, you're right.

 

However, if one only needs to execute a command when a button is pressed, then RibbonCommandButton (which is derived from RibbonCommandItem) is what they should use. It also provides for cancelling out any currently-active commands before executing the macro.

 

RibbonCommandItem is a lower-level type that is mostly useful in more specialized needs, which is not the case here.

Message 5 of 23

ActivistInvestor
Mentor
Mentor

@JamesLH88 wrote:

Hi All,

 

I wonder if anybody can help me.

 

I have a few commands that I have created, and they work great if called via the command line.

 

I have also created a new ribbon tab, with panel, and RibbonButton, and assigned a CommandHandler which calls a Action (callback function). However, I can't seem to get my button to trigger 'MyCommand'.

  


Unless you have more-specialized needs or just want to learn, the RibbonCommandButton is the easiest way to execute a command in response to a button click.

 

It only requires you to set the Macro property to the command string to be executed, and nothing else.

Message 6 of 23

JamesLH88
Explorer
Explorer

Thanks everyone for your help, I have managed to get it working now.

 

My only problem now is, how can I cancel any currently active commands, before executing my own.

 

I have seen that previous methods (chr(27) and ^C) are no longer supported?

 

 

Thanks again!

James

0 Likes
Message 7 of 23

ActivistInvestor
Mentor
Mentor
Accepted solution

@JamesLH88 wrote:

Thanks everyone for your help, I have managed to get it working now.

 

My only problem now is, how can I cancel any currently active commands, before executing my own.

 

I have seen that previous methods (chr(27) and ^C) are no longer supported?

 

 

Thanks again!

James


 

To place a button on the ribbon that executes an AutoCAD command when the user clicks on the button, you only need to do this:

 

 


// Create an instance of a RibbonCommandButton that // when clicked, will cancel out any currently-running // command, and then execute the command "MYCOMMAND" RibbonCommandButton button = new RibbonCommandButton(); button.Id = "ID_MYBUTTON1"; button.Name = "MyRibbonCommandButton1"; button.Text = button.Name; button.ShowText = true; button.Macro = "^c^cMYCOMMAND";

 

That's all that's needed. For your purposes, there is no absolutely need to provide a separate command handler that implements ICommand, because the RibbonCommandButton acts as its own command handler, internally does what has to be done to execute the command, and it provides for the means to cancel out any currently-running command by just prefixing the macro with ^C.

 

However, if for whatever reason, you want or need to use SendStringToExecute(), then this should cancel out a running command:

 


string cmd = string.Format("{0}{1}", new string((char) 03, 2), "MYCOMMAND"); doc.SendStringToExecute(cmd, true, false, true);

 

 

0 Likes
Message 8 of 23

TiStars
Advisor
Advisor
Since it was a post of 4 months ago, I don't know if you solved it or not, but I had same problem and I got a solution here:

http://adndevblog.typepad.com/autocad/2012/07/start-command-with-escape-characters-cc.html

instead of ^C, he used '\x03', and got a piece of code to help do it.

Cheers

天涯海角的山姆


您认为此帖子是否有用?欢迎为此帖点赞。

您的问题是否已得到解答?请点击“接受解答”按钮。


EESignature



0 Likes
Message 9 of 23

ActivistInvestor
Mentor
Mentor

^C is for use in the RibbonCommandButton's Macro property only, not with SendStringToExecute().

 

 

The code from above:

 

string.Format("{0}{1}", new string((char) 03, 2), "MYCOMMAND");

produces the the same result as '\x03' + '\x03'. It's just a different way of doing it.

 

 

0 Likes
Message 10 of 23

TiStars
Advisor
Advisor
Thanks, I tried your code, it runs good as well.

Actually, I am going to create a Ribbon Button for my Addins, I found there are so many ways to do it according to the information I got from forum, old or new, I just got confused to know one is the best way or official way recommended by AutoDesk to do it.

天涯海角的山姆


您认为此帖子是否有用?欢迎为此帖点赞。

您的问题是否已得到解答?请点击“接受解答”按钮。


EESignature



0 Likes
Message 11 of 23

ActivistInvestor
Mentor
Mentor

IMO, the correct way to do it, is not to get involved at all with ribbon UI elements, and just provide a partial CUI file with buttons that execute your commands.

 

Commands should be accessible via any means, not just via a ribbon button (e..g, pulldown/context menu, keyboard shortcuts, etc.).

 

The official and correct way to achieve that is to simply use the CUI, rather than tying your command to some specific interface or access method.

 

 


@TiStars wrote:
Thanks, I tried your code, it runs good as well.

Actually, I am going to create a Ribbon Button for my Addins, I found there are so many ways to do it according to the information I got from forum, old or new, I just got confused to know one is the best way or official way recommended by AutoDesk to do it.

 

Message 12 of 23

TiStars
Advisor
Advisor

Yes, I would like to implement what you said, access commands from all kinds of route.

 

Thank you very much, I will search some document/information about CUI file, but seems AutoDesk provides limited Doc for that.

I like .NET reference of Civil 3D very much as it has been make very well. Organized and enough explanation, examples, etc


天涯海角的山姆


您认为此帖子是否有用?欢迎为此帖点赞。

您的问题是否已得到解答?请点击“接受解答”按钮。


EESignature



0 Likes
Message 13 of 23

ActivistInvestor
Mentor
Mentor

@TiStars wrote:

Yes, I would like to implement what you said, access commands from all kinds of route.

 

Thank you very much, I will search some document/information about CUI file, but seems AutoDesk provides limited Doc for that.

I like .NET reference of Civil 3D very much as it has been make very well. Organized and enough explanation, examples, etc


You don't need docs on the CUI file format. AutoCAD reads and writes it. You only need to use the CUI command to create a partial CUI file that contains your buttons, etc, and give that to the end user or include it in your bundle.

0 Likes
Message 14 of 23

TiStars
Advisor
Advisor
To end user, even 1 more step will be great challenge since they got a DLL to netload and manual to read, tutorial videos to watch etc..

I'm afraid giving end user CUI file will be the last option.

My target will be one file like setup.exe, simply click&run, end user will get everything shown up in his Civil 3D.

Anyway, I would like to learn CUI file to see if I can do something with it.

Thanks!

天涯海角的山姆


您认为此帖子是否有用?欢迎为此帖点赞。

您的问题是否已得到解答?请点击“接受解答”按钮。


EESignature



0 Likes
Message 15 of 23

ActivistInvestor
Mentor
Mentor

A partial .CUI file is just another type of file that you can include in your deployment package/bundle.

 

The user doesn't have to do anything with it. Your installer or your app (on first run) can load the partial .CUI file making its contents available., so there is nothing required on the part of the end-user.

 

 

0 Likes
Message 16 of 23

dgorsman
Consultant
Consultant

"Everything showing up" is the problem though.  One of the more aggravating problems with plugins are those which *insist* on populating Ribbon content regardless of workspace, profile, or other settings.

 

Please consider that your users may not be using your tools all the time, so providing a CUIx will allow them to create workspaces to show it when they need it and hide it when they don't.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 17 of 23

TiStars
Advisor
Advisor
That seems exactly what i want, Thank you very much.
I am reading articles about CUI file from here step by step:

https://www.cad-notes.com/exploring-autocad-cui-introduction-1/

I haven't finished it yet ,but I think it doesn't include how to put CUI file into depoyment package/bundle. I will do some research about this later.

天涯海角的山姆


您认为此帖子是否有用?欢迎为此帖点赞。

您的问题是否已得到解答?请点击“接受解答”按钮。


EESignature



0 Likes
Message 18 of 23

TiStars
Advisor
Advisor
Thanks for your reminder & advice, are you suggesting me provide a separated CUI file to my users to load it when they need?

天涯海角的山姆


您认为此帖子是否有用?欢迎为此帖点赞。

您的问题是否已得到解答?请点击“接受解答”按钮。


EESignature



0 Likes
Message 19 of 23

dgorsman
Consultant
Consultant

If you have the time, I would suggest providing several options.  The first would be the "dirt simple" way you were looking at, where it does a partial load of the CUIx file for them.  The other would be to let the users do the loading themselves e.g. partial to the Enterprise CUIx file.  Include some basic documentation about how to partially load your CUIx (although that should just be a rehash to most AutoCAD/Civil3D users by now).

 

Either way, let them add and arrange panels in the workspace for themselves.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 20 of 23

TiStars
Advisor
Advisor
Thank you for your suggestions , I would like to try "dirt simple" way at this stage, but I think I should think about the other option you mentioned when my user have been familiar with how to netload my DLLs and use them at first.

天涯海角的山姆


您认为此帖子是否有用?欢迎为此帖点赞。

您的问题是否已得到解答?请点击“接受解答”按钮。


EESignature



0 Likes