From 34a2243893625bb55c924c382656dff9adb23d8c Mon Sep 17 00:00:00 2001 From: Magson Leone dos Santos Date: Fri, 12 Sep 2025 11:42:14 -0400 Subject: [PATCH 1/6] Add SetContextualHelp method to RibbonExtensions Introduced a new method `SetContextualHelp` for the `RibbonItem` class, enabling the assignment of contextual help via a URL. Comprehensive XML documentation has been added to clarify its purpose, parameters, return value, and provide usage examples. --- .../UIFrameworkExtensions/RibbonExtensions.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs index d710e3f..3c1351a 100644 --- a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs +++ b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs @@ -681,4 +681,25 @@ public static RibbonItem SetLongDescription(this RibbonItem button, string descr button.LongDescription = description; return button; } + + /// + /// Sets contextual help for the specified using a URL. + /// + /// The to which contextual help will be assigned. + /// A URL pointing to online help content (e.g., documentation, knowledge base, or support page). + /// The same instance with contextual help configured. + /// + /// Contextual help is displayed when the user clicks the help button (question mark) in the extended tooltip. + /// Only URL-based help is supported by this helper method. If you need to use other help types (e.g., chm / context id), create a instance manually and call Revit's native SetContextualHelp method. + /// + /// + /// + /// button.SetContextualHelp("https://mydomain.com/docs/command-help"); + /// + /// + public static RibbonItem SetContextualHelp(this RibbonItem button, string helpPath) + { + button.SetContextualHelp(new ContextualHelp(ContextualHelpType.Url, helpPath)); + return button; + } } \ No newline at end of file From 7a97677211b44d8220dc7c1d18fc8ae220ec79a6 Mon Sep 17 00:00:00 2001 From: Magson Leone dos Santos Date: Fri, 12 Sep 2025 11:46:11 -0400 Subject: [PATCH 2/6] Add WPF image handling and conversion method This commit introduces several using directives for WPF and image handling namespaces, enabling the use of WPF features in the Ribbon UI. A new private static method, `ConvertToImageSource`, is added to the `RibbonExtensions` class to convert `System.Drawing.Bitmap` to a WPF `ImageSource`, suitable for button icons. XML documentation comments are included for clarity. The existing code structure remains unchanged. --- .../RibbonExtensions.Helpers.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs index 72fc3f4..4bf3b01 100644 --- a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs +++ b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs @@ -1,6 +1,10 @@ -using System.Reflection; -using Autodesk.Revit.UI; +using Autodesk.Revit.UI; using Autodesk.Windows; +using System.Reflection; +using System.Windows; +using System.Windows.Interop; +using System.Windows.Media; +using System.Windows.Media.Imaging; using UIFramework; using UIFrameworkServices; using RibbonItem = Autodesk.Revit.UI.RibbonItem; @@ -128,6 +132,16 @@ private static Autodesk.Windows.RibbonPanel GetInternalPanel(this RibbonPanel pa return (Autodesk.Windows.RibbonPanel)internalField.GetValue(panel)!; } + /// + /// Converts a to a WPF suitable for use in Revit Ribbon UI (e.g., button icons). + /// + /// The GDI+ bitmap to convert. + /// An created from the specified bitmap. + private static ImageSource ConvertToImageSource(System.Drawing.Bitmap bitmap) + { + return Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); + } + #if REVIT2024_OR_GREATER /// /// Monitors the button for theme changes and updates the image accordingly. From 2162fc679070c4784c7b94feebfb21efc4585393 Mon Sep 17 00:00:00 2001 From: Magson Leone dos Santos Date: Fri, 12 Sep 2025 12:18:22 -0400 Subject: [PATCH 3/6] Add SetImage and SetLargeImage methods to RibbonExtensions Implemented two new methods, `SetImage` and `SetLargeImage`, for the `RibbonExtensions` class. These methods enable setting images for Ribbon buttons using in-memory `System.Drawing.Bitmap` objects. Comprehensive XML documentation has been added for both methods, detailing their purpose, parameters, return values, remarks, and usage examples. --- .../UIFrameworkExtensions/RibbonExtensions.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs index 3c1351a..5018c81 100644 --- a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs +++ b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs @@ -568,6 +568,29 @@ public static RibbonButton SetImage(this RibbonButton button, string uri) return button; } + /// + /// Sets a 16x16 pixel, 96dpi image for the given Ribbon button using an in-memory . + /// + /// The Ribbon button to which the image will be applied. + /// The bitmap representing the icon (ideally 16x16 at 96 dpi; larger images will be scaled by Revit/WPF). + /// The Ribbon button with the applied image. + /// + /// Use this overload when the icon is produced at runtime or loaded from a stream/embedded resource, instead of referencing it via a pack or file URI. The bitmap is converted internally to a WPF ImageSource. + /// + /// + /// + /// using (var bmp = new System.Drawing.Bitmap(resourceStream)) + /// { + /// pushButton.SetImage(bmp); + /// } + /// + /// + public static RibbonButton SetImage(this RibbonButton button, System.Drawing.Bitmap bitmap) + { + button.Image = ConvertToImageSource(bitmap); + return button; + } + /// /// Sets a 32x32 pixel, 96dpi image from the specified URI source to the given Ribbon button. /// @@ -592,6 +615,29 @@ public static RibbonButton SetLargeImage(this RibbonButton button, string uri) return button; } + /// + /// Sets a 32x32 pixel, 96dpi image for the given Ribbon button using an in-memory . + /// + /// The Ribbon button to which the large image will be applied. + /// The bitmap representing the icon (ideally 32x32 at 96 dpi; larger images will be scaled by Revit/WPF). + /// The Ribbon button with the applied large image. + /// + /// Use this overload when the large icon is produced at runtime or loaded from a stream/embedded resource, instead of referencing it via a pack or file URI. The bitmap is converted internally to a WPF ImageSource in a memory-efficient way. + /// + /// + /// + /// using (var bmp = new System.Drawing.Bitmap(resourceStream)) + /// { + /// pushButton.SetLargeImage(bmp); + /// } + /// + /// + public static RibbonButton SetLargeImage(this RibbonButton button, System.Drawing.Bitmap bitmap) + { + button.LargeImage = ConvertToImageSource(bitmap); + return button; + } + /// /// Sets the availability controller class for a PushButton. /// This class determines when the PushButton will be enabled or disabled in the Revit UI. From a4eb271cf69d1c18ff1d2c2de3003b13e63e0c7b Mon Sep 17 00:00:00 2001 From: Magson Leone dos Santos Date: Fri, 12 Sep 2025 12:28:45 -0400 Subject: [PATCH 4/6] Add System.Drawing.Common package reference Updated `Nice3point.Revit.Extensions.csproj` to include a new package reference for `System.Drawing.Common` version `8.0.8` in the `` section. --- .../Nice3point.Revit.Extensions.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Nice3point.Revit.Extensions/Nice3point.Revit.Extensions.csproj b/source/Nice3point.Revit.Extensions/Nice3point.Revit.Extensions.csproj index 778281e..736146d 100644 --- a/source/Nice3point.Revit.Extensions/Nice3point.Revit.Extensions.csproj +++ b/source/Nice3point.Revit.Extensions/Nice3point.Revit.Extensions.csproj @@ -63,6 +63,7 @@ + From 700505cab0e9165a73fc5556025d4873b7faf27a Mon Sep 17 00:00:00 2001 From: Magson Leone dos Santos Date: Fri, 12 Sep 2025 12:31:17 -0400 Subject: [PATCH 5/6] Remove unused namespace in RibbonExtensions.Helpers.cs Eliminated the `using System.Windows.Media.Imaging;` directive to clean up unused namespaces and avoid potential conflicts in the context of Revit 2024 or greater. --- .../UIFrameworkExtensions/RibbonExtensions.Helpers.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs index 4bf3b01..05fe171 100644 --- a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs +++ b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs @@ -12,7 +12,6 @@ #if REVIT2024_OR_GREATER using System.ComponentModel; using System.IO; -using System.Windows.Media.Imaging; using RibbonButton = Autodesk.Revit.UI.RibbonButton; #endif From c6170818c32d682bb5572c8ade794c8d4878d7ca Mon Sep 17 00:00:00 2001 From: Magson Leone dos Santos Date: Fri, 12 Sep 2025 12:36:13 -0400 Subject: [PATCH 6/6] Update ConvertToImageSource method documentation Clarified that the method converts a System.Drawing.Bitmap to a WPF-compatible BitmapSource. Updated parameter and return type descriptions, and added remarks about unmanaged HBITMAP handling. Changed the method signature to return BitmapSource instead of ImageSource for better specificity. --- .../RibbonExtensions.Helpers.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs index 05fe171..67cca59 100644 --- a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs +++ b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs @@ -132,11 +132,16 @@ private static Autodesk.Windows.RibbonPanel GetInternalPanel(this RibbonPanel pa } /// - /// Converts a to a WPF suitable for use in Revit Ribbon UI (e.g., button icons). + /// Converts a into a WPF-compatible . /// - /// The GDI+ bitmap to convert. - /// An created from the specified bitmap. - private static ImageSource ConvertToImageSource(System.Drawing.Bitmap bitmap) + /// The GDI+ to convert. + /// A that can be assigned to WPF image properties (e.g., Ribbon button images). + /// + /// The created holds a handle (HBITMAP) allocated by GDI. If the source bitmap is created at runtime + /// and not needed afterwards, ensure it is properly disposed. The unmanaged HBITMAP returned by GetHbitmap() is released + /// by the WPF imaging subsystem when the is garbage collected. + /// + private static BitmapSource ConvertToImageSource(System.Drawing.Bitmap bitmap) { return Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); }