Hi all,
I have been trying to Reload/refresh my added toolbar with External Command with the code in this thread;
but, so far, I have not been able. Has anyboady found a simple way of updating the buttons when a button is clicked or get the code in the thread working?
It would be really helpful.
Thanks
Solved! Go to Solution.
Solved by FAIR59. Go to Solution.
Hi,
What exactly are you trying to do?
Changing the button image?
- Michel
Yes, I am trying to change the button image and text when clicking on ExternalCommand, but the UI does not do anything.
In the thread of the link you mentioned is the code below, this looks solid.
You will need to replace the Tab id with the one you used and also Source Panel Id, and for the specific button.
Can you find the correct Button?
Do you have you're own Tab?, then loop all panels and buttons and list their Id's
They follow a distinct pattern, from which you can retrieve the Id you set for the SourcePanel and/or button.
Once you retrieve the correct RibbonItem you can alter the ItemText, ToolTip, LargeImage and more properties.
// using adwin = Autodesk.Windows;
public void Test()
{
Document doc = this.ActiveUIDocument.Document;
adwin.RibbonControl ribbon = adwin.ComponentManager.Ribbon;
adwin.RibbonTab my_tab = null;
adwin.RibbonPanel my_panel = null;
adwin.RibbonButton my_button = null;
foreach (var tab in ribbon.Tabs)
{
if (tab.Id == "Add-Ins")
{
my_tab = tab;
break;
}
}
if (my_tab==null) return;
foreach(var panel in my_tab.Panels)
{
if(panel.Source.Id == "CustomCtrl_%Add-Ins%KCAP")
{
my_panel = panel;
break;
}
}
if( my_panel==null) return;
foreach(var item in my_panel.Source.Items)
{
if (item.Id.Contains("Fa_mirror"))
{
my_button = item as adwin.RibbonButton;
break;
}
}
if (my_button == null) return;
string filepath = Path.Combine(@"K:\","ArkUser","basis.ico");
my_button.LargeImage = new System.Windows.Media.Imaging.BitmapImage(new Uri(filepath, UriKind.Absolute));
}
Thank you very much! How can I loop my own tab and buttons within the ExternalCommand to use them later? Sorry for my inexperience...
Hi,
The example is quite clear.
Document doc = this.ActiveUIDocument.Document;
adwin.RibbonControl ribbon = adwin.ComponentManager.Ribbon;
Is above the issue?
doc call can be removed, this isn't used in the sample
for retrieving the ribbon itself, see below for the full call:
Autodesk.Windows.RibbonControl ribbon = Autodesk.Windows.ComponentManager.Ribbon;
1. Get the Ribbon itself, see above.
2. Loop all Tabs until the one is found that you use, see foreach loop for ribbon.Tabs
3. If Tab found, loop all Panels until the panel is found you created, see foreach loop on my_tab.Panels
4. If panel is found loop all items (buttons) on the panel, by inspecting it's source panel.
and again see loop: my_panel.Source.Items
5. If you're button is found then change it's image, text etc...
Now If you don't know on which panel the button is, then evaluate all panels of step 3. and call step 4 for each panel and list all items found. (panel.Source.Items <= loop all items and list their id's + Title.
See the Ribbon sample in the Revit API SDK's (About the Revit SDK ) for complete commands.
Thank you very much. Apologies for the late response, my laptop shut down forever after 9 years :S , but I am now back.
I have been working trying to implement this code at the end of an ExternalCommand, so when a button is pushed, it first opens a file dialog to select a file and then update the UI (icon and button title).
So my externalcommand starts;
using System;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using System.IO;
using W = System.Windows.Forms;
using adwin = Autodesk.Windows;
namespace Nonica.PNGselection
{
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class PngS1 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
using (W.OpenFileDialog dlg = new W.OpenFileDialog())
{ ....
}
.........
AND....
adwin.RibbonControl ribbon = adwin.ComponentManager.Ribbon;
adwin.RibbonTab my_tab = null;
adwin.RibbonPanel my_panel = null;
adwin.RibbonButton my_button = null;
foreach (var tab in ribbon.Tabs)
{
if (tab.Id == "Add-Ins")
{
my_tab = tab;
break;
}
}
if (my_tab == null) return;
foreach (var panel in my_tab.Panels)
{
if (panel.Source.Id == "CustomCtrl_%Add-Ins%KCAP")
{
my_panel = panel;
break;
}
}
if (my_panel == null) return;
foreach (var item in my_panel.Source.Items)
{
if (item.Id.Contains("Fa_mirror"))
{
my_button = item as adwin.RibbonButton;
break;
}
}
if (my_button == null) return;
string filepath = Path.Combine(@"K:\", "ArkUser", "basis.ico");
my_button.LargeImage = new System.Windows.Media.Imaging.BitmapImage(new Uri(filepath, UriKind.Absolute));
}
The code brings 3 errors with the return statements;
Error CS0126 An object of a type convertible to 'Result' is required Nonica
How can I solve this?
I understand that the tab.ID for the following case is tabName, right?
String tabName = "Nonica";
application.CreateRibbonTab(tabName);
Thank you
Jaime
The Execute method has to return a Result enum value.
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
//Do something here
//message = "Operation failed, do ..."; // optionally set the byref message if return will be Cancelled or Failed, it then shows the standard failed/cancelled box of Revit.
return Result.Succeeded; // Return enum
}
See: IExternalCommand Interface and Execute Method
Thanks for your help!
I have been trying to switch the name of the button following the explanations of https://thebuildingcoder.typepad.com/blog/2012/11/roll-your-own-toggle-button.html
I set everything up except for the AvailabilityClassName that threw me and error. I am trying to change the name of button0data when another command in another command is run. My issue is the following:
Any idea what is happening? I also tried @TripleM-Dev.net solution but other errors came.
Thanks
My other try was setting inside Toggle() the code discussed;
public void Toggle()
{
adwin.RibbonControl ribbon = adwin.ComponentManager.Ribbon;
adwin.RibbonTab my_tab = null;
adwin.RibbonPanel my_panel = null;
adwin.RibbonButton my_button = null;
foreach (var tab in ribbon.Tabs)
{
if (tab.Id == "Nonica")
{
my_tab = tab;
break;
}
}
if (my_tab == null) return;
foreach (var panel in my_tab.Panels)
{
if (panel.Source.Id == "Nonica")
{
my_panel = panel;
break;
}
}
if (my_panel == null) return;
foreach (var item in my_panel.Source.Items)
{
if (item.Id.Contains("ByCategories"))
{
my_button = item as adwin.RibbonButton;
break;
}
}
if (my_button == null) return;
my_button.Text = "TEST";
my_button.ToolTip = "TEST";
}
but when pressed on the button and execute App.Instance.Toggle(); the button does nothing; no error but no action either...
The code inside the Toggle method should work. Your Id-strings for the panel and button are probably wrong, resulting in an "early" return.
This code lists all Id's to help you find the correct ones.
//using System.Text;
//StringBuilder sb = new StringBuilder();
foreach (var tab in ribbon.Tabs)
{
sb.AppendLine(string.Format("tab: {0}", tab.Id));
foreach (var panel in tab.Panels)
{
sb.AppendLine(string.Format(" panel: {0}", panel.Source.Id));
foreach (var item in panel.Source.Items)
{
if(!string.IsNullOrEmpty(item.Id)) sb.AppendLine(string.Format(" item: {0}", item.Id));
}
}
sb.AppendLine();
}
TaskDialog.Show("debug", sb.ToString());
Awesome! Thank you very much. I got the right Ids and worked like a charm with a standard pushbutton. Nonetheless, when I try with a SplitButtonData, no id is provided to buttons within the SplitButtonData and setting the id of that one does not work to change any of them. Any idea on how that could work? I will post it here if I find any solution while researching.
I finally got it working by replacing the two adwin.RibbonButton by adwin.RibbonSplitButton and adding at the end;
my_button.Current.Text = "NEW NAME";
Thanks! The issue now is resetting the image. LargeImage property does not reset the image of my splitbutton... Sorry for my inexpertise 😃
Can't find what you're looking for? Ask the community or share your knowledge.