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 } }