You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
5.7 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Data;
  9. using System.Windows.Documents;
  10. using System.Windows.Input;
  11. using System.Windows.Media;
  12. using System.Windows.Media.Imaging;
  13. using System.Windows.Navigation;
  14. using System.Windows.Shapes;
  15. namespace BPA.UIControl
  16. {
  17. /// <summary>
  18. /// 汉堡包菜单子项
  19. /// </summary>
  20. public class HamburgerMenuItem : TabItem, ICommandSource
  21. {
  22. static HamburgerMenuItem()
  23. {
  24. DefaultStyleKeyProperty.OverrideMetadata(typeof(HamburgerMenuItem), new FrameworkPropertyMetadata(typeof(HamburgerMenuItem)));
  25. }
  26. /// <inheritdoc/>
  27. public override void OnApplyTemplate()
  28. {
  29. base.OnApplyTemplate();
  30. }
  31. /// <inheritdoc/>
  32. protected override void OnSelected(RoutedEventArgs e)
  33. {
  34. base.OnSelected(e);
  35. CommandHelpers.ExecuteCommandSource(this);
  36. }
  37. #region commands
  38. /// <summary>
  39. /// Identifies the <see cref="Command"/> dependency property.
  40. /// </summary>
  41. public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
  42. nameof(Command), typeof(ICommand), typeof(HamburgerMenuItem), new PropertyMetadata(null, OnCommandPropertyChanged));
  43. private static void OnCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  44. {
  45. ((HamburgerMenuItem)d).OnCommandChanged(e.OldValue as ICommand, e.NewValue as ICommand);
  46. }
  47. /// <summary>
  48. /// Gets or sets a command which will be executed if an item is clicked by the user.
  49. /// </summary>
  50. public ICommand Command
  51. {
  52. get => (ICommand)this.GetValue(CommandProperty);
  53. set => this.SetValue(CommandProperty, value);
  54. }
  55. /// <summary>
  56. /// Identifies the <see cref="CommandParameter"/> dependency property.
  57. /// </summary>
  58. public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
  59. nameof(CommandParameter), typeof(object), typeof(HamburgerMenuItem), new PropertyMetadata(null));
  60. /// <summary>
  61. /// Gets or sets the command parameter which will be passed by the Command.
  62. /// </summary>
  63. public object CommandParameter
  64. {
  65. get => this.GetValue(CommandParameterProperty);
  66. set => this.SetValue(CommandParameterProperty, value);
  67. }
  68. /// <summary>
  69. /// Identifies the <see cref="CommandTarget"/> dependency property.
  70. /// </summary>
  71. public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register(
  72. nameof(CommandTarget), typeof(IInputElement), typeof(HamburgerMenuItem), new PropertyMetadata(null));
  73. /// <summary>
  74. /// Gets or sets the element on which to raise the specified command.
  75. /// </summary>
  76. /// <returns>
  77. /// Element on which to raise a command.
  78. /// </returns>
  79. public IInputElement CommandTarget
  80. {
  81. get => (IInputElement)this.GetValue(CommandTargetProperty);
  82. set => this.SetValue(CommandTargetProperty, value);
  83. }
  84. private void OnCommandChanged(ICommand oldCommand, ICommand newCommand)
  85. {
  86. if (oldCommand != null)
  87. {
  88. this.UnhookCommand(oldCommand);
  89. }
  90. if (newCommand != null)
  91. {
  92. this.HookCommand(newCommand);
  93. }
  94. }
  95. private void UnhookCommand(ICommand command)
  96. {
  97. CanExecuteChangedEventManager.RemoveHandler(command, this.OnCanExecuteChanged);
  98. this.UpdateCanExecute();
  99. }
  100. private void HookCommand(ICommand command)
  101. {
  102. CanExecuteChangedEventManager.AddHandler(command, this.OnCanExecuteChanged);
  103. this.UpdateCanExecute();
  104. }
  105. private void OnCanExecuteChanged(object sender, EventArgs e)
  106. {
  107. this.UpdateCanExecute();
  108. }
  109. private void UpdateCanExecute()
  110. {
  111. this.CanExecute = this.Command is null || CommandHelpers.CanExecuteCommandSource(this);
  112. }
  113. private bool canExecute = true;
  114. private bool CanExecute
  115. {
  116. get => this.canExecute;
  117. set
  118. {
  119. if (value == this.canExecute)
  120. {
  121. return;
  122. }
  123. this.canExecute = value;
  124. this.CoerceValue(IsEnabledProperty);
  125. }
  126. }
  127. #endregion commands
  128. #region properties
  129. /// <summary>
  130. /// 图标
  131. /// </summary>
  132. public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
  133. "Icon", typeof(object), typeof(HamburgerMenuItem), new PropertyMetadata(null));
  134. /// <summary>
  135. /// 图标
  136. /// </summary>
  137. public object Icon
  138. {
  139. get { return (object)GetValue(IconProperty); }
  140. set { SetValue(IconProperty, value); }
  141. }
  142. /// <summary>
  143. /// 图标类型
  144. /// </summary>
  145. public static readonly DependencyProperty IconTypeProperty = DependencyProperty.Register(
  146. "IconType", typeof(IconType?), typeof(HamburgerMenuItem), new PropertyMetadata(null));
  147. /// <summary>
  148. /// 图标类型
  149. /// </summary>
  150. public IconType? IconType
  151. {
  152. get { return (IconType?)GetValue(IconTypeProperty); }
  153. set { SetValue(IconTypeProperty, value); }
  154. }
  155. #endregion properties
  156. }
  157. }