using System.Windows.Controls; // ReSharper disable once CheckNamespace namespace WPFluent.Controls; /// /// A control that drop downs a flyout of choices from which one can be chosen. /// public class DropDownButton : Button { /// /// Identifies the dependency property. /// public static readonly DependencyProperty FlyoutProperty = DependencyProperty.Register( nameof(Flyout), typeof(object), typeof(DropDownButton), new PropertyMetadata(null, OnFlyoutChanged)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register( nameof(IsDropDownOpen), typeof(bool), typeof(DropDownButton), new PropertyMetadata(false)); private ContextMenu? _contextMenu; private static void OnFlyoutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if(d is DropDownButton dropDownButton) { dropDownButton.OnFlyoutChanged(e.NewValue); } } protected override void OnClick() { base.OnClick(); if(_contextMenu is null) { return; } _contextMenu.SetCurrentValue(MinWidthProperty, ActualWidth); _contextMenu.SetCurrentValue(ContextMenu.PlacementTargetProperty, this); _contextMenu.SetCurrentValue( ContextMenu.PlacementProperty, System.Windows.Controls.Primitives.PlacementMode.Bottom); _contextMenu.SetCurrentValue(ContextMenu.IsOpenProperty, true); } protected virtual void OnContextMenuClosed(object sender, RoutedEventArgs e) { SetCurrentValue(IsDropDownOpenProperty, false); } protected virtual void OnContextMenuOpened(object sender, RoutedEventArgs e) { SetCurrentValue(IsDropDownOpenProperty, true); } /// /// This method is invoked when the changes. /// /// The new value of . protected virtual void OnFlyoutChanged(object value) { if(value is ContextMenu contextMenu) { _contextMenu = contextMenu; _contextMenu.Opened += OnContextMenuOpened; _contextMenu.Closed += OnContextMenuClosed; } } protected virtual void OnIsDropDownOpenChanged(bool currentValue) { } /// /// Gets or sets the flyout associated with this button. /// [Bindable(true)] public object Flyout { get => GetValue(FlyoutProperty); set => SetValue(FlyoutProperty, value); } /// /// Gets or sets a value indicating whether the drop-down for a button is currently open. /// /// /// if the drop-down is open; otherwise, . The default is . /// [Bindable(true)] [Browsable(false)] [Category("Appearance")] public bool IsDropDownOpen { get => (bool)GetValue(IsDropDownOpenProperty); set => SetValue(IsDropDownOpenProperty, value); } }