Files
Shrlalgo.RvKits/WPFluent/Controls/DropDownButton/DropDownButton.cs

104 lines
3.2 KiB
C#

using System.Windows.Controls;
// ReSharper disable once CheckNamespace
namespace WPFluent.Controls;
/// <summary>
/// A control that drop downs a flyout of choices from which one can be chosen.
/// </summary>
public class DropDownButton : Button
{
/// <summary>
/// Identifies the <see cref="Flyout"/> dependency property.
/// </summary>
public static readonly DependencyProperty FlyoutProperty = DependencyProperty.Register(
nameof(Flyout),
typeof(object),
typeof(DropDownButton),
new PropertyMetadata(null, OnFlyoutChanged));
/// <summary>
/// Identifies the <see cref="IsDropDownOpen"/> dependency property.
/// </summary>
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); }
/// <summary>
/// This method is invoked when the <see cref="FlyoutProperty"/> changes.
/// </summary>
/// <param name="value">The new value of <see cref="FlyoutProperty"/>.</param>
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)
{
}
/// <summary>
/// Gets or sets the flyout associated with this button.
/// </summary>
[Bindable(true)]
public object Flyout { get => GetValue(FlyoutProperty); set => SetValue(FlyoutProperty, value); }
/// <summary>
/// Gets or sets a value indicating whether the drop-down for a button is currently open.
/// </summary>
/// <returns>
/// <see langword="true"/> if the drop-down is open; otherwise, <see langword="false"/>. The default is <see
/// langword="false"/>.
/// </returns>
[Bindable(true)]
[Browsable(false)]
[Category("Appearance")]
public bool IsDropDownOpen
{
get => (bool)GetValue(IsDropDownOpenProperty);
set => SetValue(IsDropDownOpenProperty, value);
}
}