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 @@ + diff --git a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.Helpers.cs index 72fc3f4..67cca59 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; @@ -8,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 @@ -128,6 +131,21 @@ private static Autodesk.Windows.RibbonPanel GetInternalPanel(this RibbonPanel pa return (Autodesk.Windows.RibbonPanel)internalField.GetValue(panel)!; } + /// + /// Converts a into a WPF-compatible . + /// + /// 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()); + } + #if REVIT2024_OR_GREATER /// /// Monitors the button for theme changes and updates the image accordingly. diff --git a/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs b/source/Nice3point.Revit.Extensions/UIFrameworkExtensions/RibbonExtensions.cs index d710e3f..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. @@ -681,4 +727,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