From 8aa371aebdb9f9e0a64e523533bd48801e13248f Mon Sep 17 00:00:00 2001 From: Vincent Gromfeld Date: Wed, 13 May 2026 16:09:14 +0200 Subject: [PATCH 1/4] Add options flyout to Ribbon --- .../Ribbon/samples/RibbonCustomSample.xaml | 11 ++- components/Ribbon/src/Ribbon.cs | 72 +++++++++++++++++++ components/Ribbon/src/RibbonStyle.xaml | 25 +++++++ 3 files changed, 107 insertions(+), 1 deletion(-) diff --git a/components/Ribbon/samples/RibbonCustomSample.xaml b/components/Ribbon/samples/RibbonCustomSample.xaml index e7d6a27bf..3277c8599 100644 --- a/components/Ribbon/samples/RibbonCustomSample.xaml +++ b/components/Ribbon/samples/RibbonCustomSample.xaml @@ -27,7 +27,16 @@ - + + + + + + + + SetValue(ScrollStepProperty, value); } + /// + /// The DP to store the property value. + /// + public static readonly DependencyProperty OptionsFlyoutProperty = DependencyProperty.Register( + nameof(OptionsFlyout), + typeof(FlyoutBase), + typeof(Ribbon), + new PropertyMetadata(null)); + + /// + /// The flyout to display when the user clicks on the ribbon options button. + /// + public FlyoutBase OptionsFlyout + { + get => (FlyoutBase)GetValue(OptionsFlyoutProperty); + set => SetValue(OptionsFlyoutProperty, value); + } + + /// + /// The DP to store the property value. + /// + public static readonly DependencyProperty OptionsAccessibleNameProperty = DependencyProperty.Register( + nameof(OptionsAccessibleName), + typeof(string), + typeof(Ribbon), + new PropertyMetadata(string.Empty, OnOptionsFlyoutPropertyChanged)); + + /// + /// The accessible name for the options button. + /// + public string OptionsAccessibleName + { + get => (string)GetValue(OptionsAccessibleNameProperty); + set => SetValue(OptionsAccessibleNameProperty, value); + } + + /// + /// The DP to store the property value. + /// + public static readonly DependencyProperty OptionsAccessKeyProperty = DependencyProperty.Register( + nameof(OptionsAccessKey), + typeof(string), + typeof(Ribbon), + new PropertyMetadata(string.Empty)); + + /// + /// The access key to set on the options flyout button/ + /// + public string OptionsAccessKey + { + get => (string)GetValue(OptionsAccessKeyProperty); + set => SetValue(OptionsAccessKeyProperty, value); + } + public Ribbon() { DefaultStyleKey = typeof(Ribbon); @@ -97,6 +156,8 @@ protected override void OnApplyTemplate() _scrollViewer.SizeChanged += OnSizeChanged; UpdateScrollButtonsState(); } + + UpdateOptionsFlyoutState(); } private void OnItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) @@ -198,4 +259,15 @@ private void OnDecrementScrollViewer(object sender, RoutedEventArgs e) private void OnIncrementScrollViewer(object sender, RoutedEventArgs e) => _scrollViewer?.ChangeView(_scrollViewer.HorizontalOffset + ScrollStep, verticalOffset: null, zoomFactor: null); + + private static void OnOptionsFlyoutPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ribbon = (Ribbon)d; + ribbon.UpdateOptionsFlyoutState(); + } + + private void UpdateOptionsFlyoutState() => VisualStateManager.GoToState( + this, + OptionsFlyout != null ? OptionsVisibleStateTemplatePart : OptionsCollapsedStateTemplatePart, + useTransitions: true); } diff --git a/components/Ribbon/src/RibbonStyle.xaml b/components/Ribbon/src/RibbonStyle.xaml index 9fe9a5468..31cf64638 100644 --- a/components/Ribbon/src/RibbonStyle.xaml +++ b/components/Ribbon/src/RibbonStyle.xaml @@ -358,6 +358,7 @@ + @@ -380,6 +381,14 @@ + + + + + + + + + + From 0f96a13e8b5b6ff634289ce51b077d8f24cb489f Mon Sep 17 00:00:00 2001 From: Vincent Gromfeld Date: Wed, 13 May 2026 17:00:25 +0200 Subject: [PATCH 2/4] fix pr comments --- components/Ribbon/src/Ribbon.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/Ribbon/src/Ribbon.cs b/components/Ribbon/src/Ribbon.cs index 438c57e03..d383801e5 100644 --- a/components/Ribbon/src/Ribbon.cs +++ b/components/Ribbon/src/Ribbon.cs @@ -67,14 +67,14 @@ public double ScrollStep nameof(OptionsFlyout), typeof(FlyoutBase), typeof(Ribbon), - new PropertyMetadata(null)); + new PropertyMetadata(null, OnOptionsFlyoutPropertyChanged)); /// /// The flyout to display when the user clicks on the ribbon options button. /// - public FlyoutBase OptionsFlyout + public FlyoutBase? OptionsFlyout { - get => (FlyoutBase)GetValue(OptionsFlyoutProperty); + get => (FlyoutBase?)GetValue(OptionsFlyoutProperty); set => SetValue(OptionsFlyoutProperty, value); } @@ -85,7 +85,7 @@ public FlyoutBase OptionsFlyout nameof(OptionsAccessibleName), typeof(string), typeof(Ribbon), - new PropertyMetadata(string.Empty, OnOptionsFlyoutPropertyChanged)); + new PropertyMetadata(string.Empty)); /// /// The accessible name for the options button. @@ -106,7 +106,7 @@ public string OptionsAccessibleName new PropertyMetadata(string.Empty)); /// - /// The access key to set on the options flyout button/ + /// The access key to set on the options flyout button. /// public string OptionsAccessKey { From 82625427c415cc6e409f520bd7480f69cb8be23a Mon Sep 17 00:00:00 2001 From: Vincent Gromfeld Date: Tue, 2 Jun 2026 10:46:05 +0200 Subject: [PATCH 3/4] addressing comments --- components/Ribbon/src/Ribbon.cs | 66 ++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/components/Ribbon/src/Ribbon.cs b/components/Ribbon/src/Ribbon.cs index d383801e5..92af913ad 100644 --- a/components/Ribbon/src/Ribbon.cs +++ b/components/Ribbon/src/Ribbon.cs @@ -52,13 +52,31 @@ public sealed partial class Ribbon : Control new PropertyMetadata(20.0)); /// - /// The amount to add or remove from the current scroll position. + /// The DP to store the property value. /// - public double ScrollStep - { - get => (double)GetValue(ScrollStepProperty); - set => SetValue(ScrollStepProperty, value); - } + public static readonly DependencyProperty OptionsFlyoutProperty = DependencyProperty.Register( + nameof(OptionsFlyout), + typeof(FlyoutBase), + typeof(Ribbon), + new PropertyMetadata(null, OnOptionsFlyoutPropertyChanged)); + + /// + /// The DP to store the property value. + /// + public static readonly DependencyProperty OptionsAccessibleNameProperty = DependencyProperty.Register( + nameof(OptionsAccessibleName), + typeof(string), + typeof(Ribbon), + new PropertyMetadata(string.Empty)); + + /// + /// The DP to store the property value. + /// + public static readonly DependencyProperty OptionsAccessKeyProperty = DependencyProperty.Register( + nameof(OptionsAccessKey), + typeof(string), + typeof(Ribbon), + new PropertyMetadata(string.Empty)); /// /// The DP to store the property value. @@ -122,6 +140,42 @@ public Ribbon() _items.CollectionChanged += OnItemsCollectionChanged; } + /// + /// Gets or sets the amount to add or remove from the current scroll position. + /// + public double ScrollStep + { + get => (double)GetValue(ScrollStepProperty); + set => SetValue(ScrollStepProperty, value); + } + + /// + /// Gets or sets the flyout to display when the user clicks on the ribbon options button. + /// + public FlyoutBase? OptionsFlyout + { + get => (FlyoutBase?)GetValue(OptionsFlyoutProperty); + set => SetValue(OptionsFlyoutProperty, value); + } + + /// + /// Gets or sets the accessible name for the options button. + /// + public string OptionsAccessibleName + { + get => (string)GetValue(OptionsAccessibleNameProperty); + set => SetValue(OptionsAccessibleNameProperty, value); + } + + /// + /// Gets or sets the access key to set on the options flyout button. + /// + public string OptionsAccessKey + { + get => (string)GetValue(OptionsAccessKeyProperty); + set => SetValue(OptionsAccessKeyProperty, value); + } + public IList Items => _items; protected override void OnApplyTemplate() From aa59c33cd568fe048b49e0ea20c8043ff6b36667 Mon Sep 17 00:00:00 2001 From: Vincent Gromfeld Date: Tue, 2 Jun 2026 11:15:05 +0200 Subject: [PATCH 4/4] fix build --- components/Ribbon/src/Ribbon.cs | 54 --------------------------------- 1 file changed, 54 deletions(-) diff --git a/components/Ribbon/src/Ribbon.cs b/components/Ribbon/src/Ribbon.cs index 92af913ad..93d0eb0a7 100644 --- a/components/Ribbon/src/Ribbon.cs +++ b/components/Ribbon/src/Ribbon.cs @@ -78,60 +78,6 @@ public sealed partial class Ribbon : Control typeof(Ribbon), new PropertyMetadata(string.Empty)); - /// - /// The DP to store the property value. - /// - public static readonly DependencyProperty OptionsFlyoutProperty = DependencyProperty.Register( - nameof(OptionsFlyout), - typeof(FlyoutBase), - typeof(Ribbon), - new PropertyMetadata(null, OnOptionsFlyoutPropertyChanged)); - - /// - /// The flyout to display when the user clicks on the ribbon options button. - /// - public FlyoutBase? OptionsFlyout - { - get => (FlyoutBase?)GetValue(OptionsFlyoutProperty); - set => SetValue(OptionsFlyoutProperty, value); - } - - /// - /// The DP to store the property value. - /// - public static readonly DependencyProperty OptionsAccessibleNameProperty = DependencyProperty.Register( - nameof(OptionsAccessibleName), - typeof(string), - typeof(Ribbon), - new PropertyMetadata(string.Empty)); - - /// - /// The accessible name for the options button. - /// - public string OptionsAccessibleName - { - get => (string)GetValue(OptionsAccessibleNameProperty); - set => SetValue(OptionsAccessibleNameProperty, value); - } - - /// - /// The DP to store the property value. - /// - public static readonly DependencyProperty OptionsAccessKeyProperty = DependencyProperty.Register( - nameof(OptionsAccessKey), - typeof(string), - typeof(Ribbon), - new PropertyMetadata(string.Empty)); - - /// - /// The access key to set on the options flyout button. - /// - public string OptionsAccessKey - { - get => (string)GetValue(OptionsAccessKeyProperty); - set => SetValue(OptionsAccessKeyProperty, value); - } - public Ribbon() { DefaultStyleKey = typeof(Ribbon);