WPF ToolBar - detect when an item is set to ToolBarOverflowPanel

I know the IsOverflowOpen and HasOverflowItems properties, but I'm looking for a way to find out if an element (button, radioobutton ...) has moved to ToolBarOverflowPanel so that I can use a trigger to change its style.

I need this to be able to play some styles of the UWP ToolBar (Windows 10 Mail, Word, Excel ...). I have successfully reproduced most of the style, and the only missing bit is the ability to change the style of my element when it is in the overflow panel.

In the screenshot of what I'm trying to reproduce, you can clearly see that the Special Ident and Line Spacing buttons change the style based on whether they are displayed or overflowed. Windows 10 ToolBar Style Screenshot

+5
source share
1 answer

You cannot do this only with xaml. You must either use the code behind, or create some attached properties.

Here is the solution with AttachedProperty:

First you need to create a helper class that displays 2 properties:

  • The IsInOverflowPanel property for reading, which you will use to trigger a style change.
  • The TrackParentPanel property, which is the enable / disable mechanism.

Here is the implementation:

public static class ToolBarHelper { public static readonly DependencyPropertyKey IsInOverflowPanelKey = DependencyProperty.RegisterAttachedReadOnly("IsInOverflowPanel", typeof(bool), typeof(ToolBarHelper), new PropertyMetadata(false)); public static readonly DependencyProperty IsInOverflowPanelProperty = IsInOverflowPanelKey.DependencyProperty; [AttachedPropertyBrowsableForType(typeof(UIElement))] public static bool GetIsInOverflowPanel(UIElement target) { return (bool)target.GetValue(IsInOverflowPanelProperty); } public static readonly DependencyProperty TrackParentPanelProperty = DependencyProperty.RegisterAttached("TrackParentPanel", typeof(bool), typeof(ToolBarHelper), new PropertyMetadata(false, OnTrackParentPanelPropertyChanged)); public static void SetTrackParentPanel(DependencyObject d, bool value) { d.SetValue(TrackParentPanelProperty, value); } public static bool GetTrackParentPanel(DependencyObject d) { return (bool)d.GetValue(TrackParentPanelProperty); } private static void OnTrackParentPanelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var element = d as UIElement; if (element != null) { bool newValue = (bool)e.NewValue; if (newValue) { element.LayoutUpdated += (s, arg) => OnControlLayoutUpdated(element); } } } private static void OnControlLayoutUpdated(UIElement element) { var isInOverflow = TreeHelper.FindParent<ToolBarOverflowPanel>(element) != null; element.SetValue(IsInOverflowPanelKey, isInOverflow); } } public static class TreeHelper { public static T FindParent<T>(this DependencyObject obj) where T : DependencyObject { return obj.GetAncestors().OfType<T>().FirstOrDefault(); } public static IEnumerable<DependencyObject> GetAncestors(this DependencyObject element) { do { yield return element; element = VisualTreeHelper.GetParent(element); } while (element != null); } } 

Then, for each item that you want to change the style, follow these steps:

 <Button x:Name="DeleteButton" Content="Delete" helpers:ToolBarHelper.TrackParentPanel="True"> <Button.Style> <Style BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" TargetType="{x:Type Button}"> <Style.Triggers> <Trigger Property="helpers:ToolBarHelper.IsInOverflowPanel" Value="True"> <!-- The Overflow style setters --> </Trigger> </Style.Triggers> </Style> </Button.Style> </Button> 
+5
source

Source: https://habr.com/ru/post/1246130/


All Articles