This may be an easy one, but so far I am struggling to find anything specific about it. How do you make a StackedItem where the icons are 24x24 when there are only 2 in the stack? It seems like it should be possible as it is used multiple times in the modify tab (see example below).
I have been able to set the ShowText property to false to get the 3 stacked icons, but when I use the same methodology with the 2 icon stack it remains 16x16 regardless of the icon resolution. I have tried to obtain and change the button's height and width, minWidth and minHeight through the Autodesk.Window.RibbonItem object to no avail. Has anyone had any success in creating these icons?
Solved! Go to Solution.
Solved by jnyp. Go to Solution.
I found a solution. In order to display the button at the 24x24 size the Autodesk.Windows.RibbonItem.Size needs to be manually set to Autodesk.Windows.RibbonItemSize.Large enum and a 24x24 icon needs to be set to the LargeImage property of the button. I have included a code example below. Forgive me for any poor coding techniques. I am only a couple months into my C# developer life.
using Autodesk.Revit.UI; using Autodesk.Windows; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Windows.Media.Imaging; using YourCustomUtilityLibrary; namespace ReallyCoolAddin { public class StackedButton { public IList<Autodesk.Revit.RibbonItem> Create(RibbonPanel ribbonPanel) { // Get Assembly Assembly assembly = Assembly.GetExecutingAssembly(); string assemblyLocation = assembly.Location; // Get DLL Location string executableLocation = Path.GetDirectoryName(assemblyLocation); string dllLocationTest = Path.Combine(executableLocation, "TestDLLName.dll"); // Set Image BitmapSource pb1Image = UTILImage.GetEmbeddedImage(assembly, "Resources.16x16_Button1.ico"); BitmapSource pb2Image = UTILImage.GetEmbeddedImage(assembly, "Resources.16x16_Button2.ico"); BitmapSource pb1LargeImage = UTILImage.GetEmbeddedImage(assembly, "Resources.24x24_Button1.ico"); BitmapSource pb2LargeImage = UTILImage.GetEmbeddedImage(assembly, "Resources.24x24_Button2.ico"); // Set Button Name string buttonName1 = "ButtonTest1"; string buttonName2 = "ButtonTest2"; // Create push buttons PushButtonData buttondata1 = new PushButtonData(buttonName1, buttonTextTest, dllLocationTest, "Command1"); buttondata1.Image = pb1Image; buttondata1.LargeImage = pb1LargeImage; PushButtonData buttondata2 = new PushButtonData(buttonName2, buttonTextTest, dllLocationTest, "Command2"); buttondata2.Image = pb2Image; buttondata2.LargeImage = pb2LargeImage; // Create StackedItem IList<Autodesk.Revit.RibbonItem> ribbonItem = ribbonPanel.AddStackedItems(buttondata1, buttondata2); // Find Autodes.Windows.RibbonItems UTILRibbonItem utilRibbon = new UTILRibbonItem(); var btnTest1 = utilRibbon.getButton("Tab", "Panel", buttonName1); var btnTest2 = utilRibbon.getButton("Tab", "Panel", buttonName2); // Set Size and Text Visibility btnTest1.Size = RibbonItemSize.Large; btnTest1.ShowText = false; btnTest2.Size = RibbonItemSize.Large; btnTest2.ShowText = false; // Return StackedItem return ribbonItem; } } }
Thank you very much for sharing this useful solution. Your coding looks absolutely perfect to me. Congratulations on getting up to speed so fast!
Hi Jameson, in your code:
// Find Autodes.Windows.RibbonItems UTILRibbonItem utilRibbon = new UTILRibbonItem(); var btnTest1 = utilRibbon.getButton("Tab", "Panel", buttonName1); var btnTest2 = utilRibbon.getButton("Tab", "Panel", buttonName2);
What is the UTILRibbonItem ? I wasn't able to find it on google or Api.
Thanks.
Z.achitecht.com,
The UTILRibbonItem class is a helper class that I use to go find RibbonItems through the Autodesk.Windows (AW) API. It goes in to the AW and recursively searches through the tabs, panels and buttons to find the button you feed to it. Taking all of the logic and putting it in it's own class allows for easier reuse. A larger discussion of what that class contains, can be found in this post Create Ribbon Panel. A basic implementation is below.
using AW = Autodesk.Windows;
public AW.RibbonItem GetButton(string tabName, string panelName, string itemName) { AW.RibbonControl ribbon = AW.ComponentManager.Ribbon; foreach(AW.RibbonTab tab in ribbon.Tabs) { if(tab.Name == tabName) { foreach(AW.RibbonPanel panel in tab.Panels) { if(panel.Source.Title == panelName) { return panel.FindItem("CustomCtrl_%CustomCtrl_%" + tabName + "%" + panelName + "%" + itemName, true) as AW.RibbonItem; } } } } return null; }
Just beware the AW API is not a documented API, so use it at your own risk as it can be changed without letting anyone know.
Thanks for the example! That really helps with my intention of stacking 2 buttons up and down.
I believe you wouldnt need your custom helper class to search for the button you just created.
After your add stack method, you can just call your button by doing so:
PushButton btnTest1 = ribbonItem[0] as PushButton PushButton btnTest2 = ribbonItem[1] as PushButton
as AddStackedItems returns IList<RibbonItem> where RibbonItem is a base class of PushButton.
Nevertheless, congrats on solving your own issue!
The Pushbutton class is of the Revit API under Autodesk.Revit, which doesn't provide access to changing stacked ribbon item size. That is why the original answer suggested using the search method under Autodesk.Windows which is not officially supported but does allow stack icons up 24x24 up and down.
This is a very impressive solution!! If the Autodesk.Windows API is undocumented and technically unsupported, how did you go about learning how to create this implementation?
I'm interested in using a similar approach for smaller double-stacked ribbon buttons, but I wonder if undocumented changes in the Autodesk.Windows API at version change could hamstring an addin that depends on it.
I have been able to set the Et20slam ShowText property to false to get the 3 stacked icons, but when I use the same methodology with the 2 icon stack it remains 16x16 regardless of the icon resolution. I have tried to obtain and change the button's height and width, minWidth and minHeight through the Autodesk.Window.RibbonItem object to no avail. Has anyone had any success in creating these icons?
Hi,
I've succeed 🙂
With text:
Without texts:
var revitRibbonItem = UIFramework.RevitRibbonControl.RibbonControl.findRibbonItemById(ribbonItem.GetId());
if (useMediumIconSize)
revitRibbonItem.Size = RibbonItemSize.Large;
if (hideButtonCaption)
revitRibbonItem.ShowText = false;
GetId is an extension method:
internal static class RibbonItemExtensions
{
public static string GetId(this RibbonItem ribbonItem)
{
var type = typeof(RibbonItem);
var parentId = type
.GetField("m_parentId", BindingFlags.Instance | BindingFlags.NonPublic)
?.GetValue(ribbonItem) ?? string.Empty;
var generateIdMethod = type
.GetMethod("generateId", BindingFlags.Static | BindingFlags.NonPublic);
return (string)generateIdMethod?.Invoke(ribbonItem, new[] { parentId, ribbonItem.Name });
}
}
You can see the Autodesk.Windows namespace documentation here Autodesk.Windows Namespace