using BPA.UIControl.Commons.KnownBoxes;
using System;
using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
namespace BPA.UIControl
{
///
/// 汉堡包菜单
///
[StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(HamburgerMenuItem))]
[StyleTypedProperty(Property = "OptionsItemContainerStyle", StyleTargetType = typeof(HamburgerMenuOptionsItem))]
[TemplatePart(Name = HamburgerButtonPartName, Type = typeof(Button))]
[TemplatePart(Name = OptionsItemsControlPartName, Type = typeof(MenuBase))]
[TemplatePart(Name = ContentTransitionPartName, Type = typeof(Transition))]
public class HamburgerMenu : TabControl
{
///
/// 汉堡包按钮
///
public const string HamburgerButtonPartName = "PART_HamburgerButton";
///
/// 选项集合控件
///
public const string OptionsItemsControlPartName = "PART_OptionsItemsControl";
///
/// 内容转换
///
public const string ContentTransitionPartName = "PART_ContentTransition";
#region fields
private CornerRadius _cornerRadius;
private MenuBase optionsMenu;
private Transition contentTransition;
#endregion fields
#region properties
///
/// 圆角半径
///
public static readonly DependencyProperty CornerRadiusProperty = Border.CornerRadiusProperty.AddOwner(typeof(HamburgerMenu), new FrameworkPropertyMetadata(default(CornerRadius), FrameworkPropertyMetadataOptions.AffectsMeasure));
///
/// 圆角半径
///
public CornerRadius CornerRadius
{
get => _cornerRadius;
set => SetValue(CornerRadiusProperty, value);
}
///
/// 是否展开菜单
///
public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register(
"IsExpanded", typeof(bool), typeof(HamburgerMenu), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
///
/// 是否展开菜单
///
public bool IsExpanded
{
get { return (bool)GetValue(IsExpandedProperty); }
set { SetValue(IsExpandedProperty, BooleanBoxes.Box(value)); }
}
///
/// 标题
///
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
"Header", typeof(string), typeof(HamburgerMenu), new PropertyMetadata(default(string)));
///
/// 标题
///
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
///
/// 面板头部内容
///
public static readonly DependencyProperty PaneHeaderProperty = DependencyProperty.Register(
"PaneHeader", typeof(object), typeof(HamburgerMenu), new PropertyMetadata(default(object)));
///
/// 面板头部内容
///
public object PaneHeader
{
get { return (object)GetValue(PaneHeaderProperty); }
set { SetValue(PaneHeaderProperty, value); }
}
///
/// 面板底部内容
///
public static readonly DependencyProperty PaneFooterProperty = DependencyProperty.Register(
"PaneFooter", typeof(object), typeof(HamburgerMenu), new PropertyMetadata(default(object)));
///
/// 面板底部内容
///
public object PaneFooter
{
get { return (object)GetValue(PaneFooterProperty); }
set { SetValue(PaneFooterProperty, value); }
}
///
/// 折叠宽度
///
public static readonly DependencyProperty CollapsedWidthProperty = DependencyProperty.Register(
"CollapsedWidth", typeof(double), typeof(HamburgerMenu), new PropertyMetadata(default(double)));
///
/// 折叠宽度
///
public double CollapsedWidth
{
get { return (double)GetValue(CollapsedWidthProperty); }
set { SetValue(CollapsedWidthProperty, value); }
}
///
/// 展开宽度
///
public static readonly DependencyProperty ExpandedWidthProperty = DependencyProperty.Register(
"ExpandedWidth", typeof(double), typeof(HamburgerMenu), new PropertyMetadata(default(double)));
///
/// 展开宽度
///
public double ExpandedWidth
{
get { return (double)GetValue(ExpandedWidthProperty); }
set { SetValue(ExpandedWidthProperty, value); }
}
///
/// 是否显示汉堡包按钮
///
public static readonly DependencyProperty IsShowHamburgerButtonProperty = DependencyProperty.Register(
"IsShowHamburgerButton", typeof(bool), typeof(HamburgerMenu), new PropertyMetadata(BooleanBoxes.TrueBox));
///
/// 是否显示汉堡包按钮
///
public bool IsShowHamburgerButton
{
get { return (bool)GetValue(IsShowHamburgerButtonProperty); }
set { SetValue(IsShowHamburgerButtonProperty, BooleanBoxes.Box(value)); }
}
///
/// 是否显示小竖条
///
public static readonly DependencyProperty IsShowLittleBarProperty = DependencyProperty.Register(
"IsShowLittleBar", typeof(bool), typeof(HamburgerMenu), new PropertyMetadata(BooleanBoxes.TrueBox));
///
/// 是否显示小竖条
///
public bool IsShowLittleBar
{
get { return (bool)GetValue(IsShowLittleBarProperty); }
set { SetValue(IsShowLittleBarProperty, BooleanBoxes.Box(value)); }
}
///
/// 转换类型
///
public static readonly DependencyProperty TransitionTypeProperty =
DependencyProperty.Register("TransitionType", typeof(TransitionType), typeof(HamburgerMenu), new PropertyMetadata(default(TransitionType)));
///
/// 转换类型
///
public TransitionType TransitionType
{
get { return (TransitionType)GetValue(TransitionTypeProperty); }
set { SetValue(TransitionTypeProperty, value); }
}
///
/// 动画时长
///
public static readonly DependencyProperty TransitionDurationProperty =
DependencyProperty.Register("TransitionDuration", typeof(Duration), typeof(HamburgerMenu), new PropertyMetadata(default(Duration)));
///
/// 动画时长
///
public Duration TransitionDuration
{
get { return (Duration)GetValue(TransitionDurationProperty); }
set { SetValue(TransitionDurationProperty, value); }
}
///
/// 面板背景
///
public static readonly DependencyProperty PaneBackgroundProperty =
DependencyProperty.Register("PaneBackground", typeof(Brush), typeof(HamburgerMenu), new PropertyMetadata(default(Brush)));
///
/// 面板背景
///
public Brush PaneBackground
{
get { return (Brush)GetValue(PaneBackgroundProperty); }
set { SetValue(PaneBackgroundProperty, value); }
}
///
/// 面板边框
///
public static readonly DependencyProperty PaneBorderThicknessProperty =
DependencyProperty.Register("PaneBorderThickness", typeof(Thickness), typeof(HamburgerMenu), new PropertyMetadata(default(Thickness)));
///
/// 面板边框
///
public Thickness PaneBorderThickness
{
get { return (Thickness)GetValue(PaneBorderThicknessProperty); }
set { SetValue(PaneBorderThicknessProperty, value); }
}
///
/// 面板圆角半径
///
public static readonly DependencyProperty PaneBorderCornerRadiusProperty =
DependencyProperty.Register("PaneBorderCornerRadius", typeof(CornerRadius), typeof(HamburgerMenu), new PropertyMetadata(default(CornerRadius)));
///
/// 面板圆角半径
///
public CornerRadius PaneBorderCornerRadius
{
get { return (CornerRadius)GetValue(PaneBorderCornerRadiusProperty); }
set { SetValue(PaneBorderCornerRadiusProperty, value); }
}
#endregion properties
#region options item
// form https://github.com/MahApps/MahApps.Metro
// MahApps.Metro.Controls.HamburgerMenu
/// Identifies the dependency property.
public static readonly DependencyProperty OptionsItemsSourceProperty = DependencyProperty.Register(
nameof(OptionsItemsSource), typeof(IEnumerable), typeof(HamburgerMenu), new PropertyMetadata(null));
///
/// Gets or sets an object source used to generate the content of the options.
///
public IEnumerable OptionsItemsSource
{
get => (IEnumerable)this.GetValue(OptionsItemsSourceProperty);
set => this.SetValue(OptionsItemsSourceProperty, value);
}
/// Identifies the dependency property.
public static readonly DependencyProperty OptionsItemContainerStyleProperty = DependencyProperty.Register(
nameof(OptionsItemContainerStyle), typeof(Style), typeof(HamburgerMenu), new PropertyMetadata(null));
///
/// Gets or sets the used for each item in the options.
///
public Style OptionsItemContainerStyle
{
get => (Style)this.GetValue(OptionsItemContainerStyleProperty);
set => this.SetValue(OptionsItemContainerStyleProperty, value);
}
/// Identifies the dependency property.
public static readonly DependencyProperty OptionsItemTemplateProperty = DependencyProperty.Register(
nameof(OptionsItemTemplate), typeof(DataTemplate), typeof(HamburgerMenu), new PropertyMetadata(null));
///
/// Gets or sets the used to display each item in the options.
///
public DataTemplate OptionsItemTemplate
{
get => (DataTemplate)this.GetValue(OptionsItemTemplateProperty);
set => this.SetValue(OptionsItemTemplateProperty, value);
}
/// Identifies the dependency property.
public static readonly DependencyProperty OptionsItemTemplateSelectorProperty = DependencyProperty.Register(
nameof(OptionsItemTemplateSelector), typeof(DataTemplateSelector), typeof(HamburgerMenu), new PropertyMetadata(null));
///
/// Gets or sets the used to display each item in the options.
///
public DataTemplateSelector OptionsItemTemplateSelector
{
get => (DataTemplateSelector)this.GetValue(OptionsItemTemplateSelectorProperty);
set => this.SetValue(OptionsItemTemplateSelectorProperty, value);
}
/// Identifies the dependency property.
public static readonly DependencyProperty OptionsVisibilityProperty = DependencyProperty.Register(
nameof(OptionsVisibility), typeof(Visibility), typeof(HamburgerMenu), new PropertyMetadata(Visibility.Visible));
///
/// Gets or sets the of the options menu.
///
public Visibility OptionsVisibility
{
get => (Visibility)this.GetValue(OptionsVisibilityProperty);
set => this.SetValue(OptionsVisibilityProperty, value);
}
///
/// Gets the collection used to generate the content of the option list.
///
///
/// Exception thrown if OptionsListView is not yet defined.
///
public ItemCollection OptionsItems
{
get
{
if (this.optionsMenu is null)
{
throw new Exception("OptionsListView is not defined yet. Please use OptionsItemsSource instead.");
}
return this.optionsMenu.Items;
}
}
#endregion options item
#region events
///
/// 汉堡包按钮点击事件
///
public static readonly RoutedEvent HamburgerButtonClickEvent = EventManager.RegisterRoutedEvent(nameof(HamburgerButtonClick), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(HamburgerMenu));
///
/// 汉堡包按钮点击
///
public event RoutedEventHandler HamburgerButtonClick
{
add => this.AddHandler(HamburgerButtonClickEvent, value);
remove => this.RemoveHandler(HamburgerButtonClickEvent, value);
}
#endregion events
static HamburgerMenu()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(HamburgerMenu), new FrameworkPropertyMetadata(typeof(HamburgerMenu)));
}
#region methods
///
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Button button = GetTemplateChild(HamburgerButtonPartName) as Button;
button.Click += Button_Click;
optionsMenu = GetTemplateChild(OptionsItemsControlPartName) as MenuBase;
contentTransition = GetTemplateChild(ContentTransitionPartName) as Transition;
SelectionChanged += HamburgerMenu_SelectionChanged;
}
private void HamburgerMenu_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.OriginalSource.GetHashCode() == GetHashCode())
{
Transition.ShowAnimation(contentTransition);
}
}
///
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is HamburgerMenuItem;
}
///
protected override DependencyObject GetContainerForItemOverride()
{
return new HamburgerMenuItem();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var args = new RoutedEventArgs(HamburgerButtonClickEvent, sender);
this.RaiseEvent(args);
if (!args.Handled)
{
IsExpanded = !IsExpanded;
}
}
#endregion methods
}
}