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.

140 lines
5.4 KiB

  1. using BPA.UIControl.Commons.KnownBoxes;
  2. using System;
  3. using System.Collections;
  4. using System.Windows;
  5. using System.Windows.Controls;
  6. using System.Windows.Controls.Primitives;
  7. namespace BPA.UIControl
  8. {
  9. /// <summary>
  10. /// 下拉按钮
  11. /// </summary>
  12. [StyleTypedProperty(Property = "MenuItemContainerStyle", StyleTargetType = typeof(MenuItem))]
  13. [TemplatePart(Name = DropDownMenuItemName, Type = typeof(MenuItem))]
  14. public class DropDownButton : Button
  15. {
  16. const string DropDownMenuItemName = "PART_DropDownMenuItem";
  17. private MenuItem dropDownMenu;
  18. /// <summary>
  19. /// 是否打开下拉菜单
  20. /// </summary>
  21. public static readonly DependencyProperty IsDropDownOpenProperty =
  22. DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(DropDownButton), new PropertyMetadata(BooleanBoxes.FalseBox));
  23. /// <summary>
  24. /// 是否显示分割线
  25. /// </summary>
  26. public static readonly DependencyProperty IsShowSeparatorProperty =
  27. DependencyProperty.Register("IsShowSeparator", typeof(bool), typeof(DropDownButton), new PropertyMetadata(BooleanBoxes.FalseBox));
  28. static DropDownButton()
  29. {
  30. DefaultStyleKeyProperty.OverrideMetadata(typeof(DropDownButton), new FrameworkPropertyMetadata(typeof(DropDownButton)));
  31. }
  32. /// <summary>
  33. /// 是否打开下拉菜单
  34. /// </summary>
  35. public bool IsDropDownOpen
  36. {
  37. get { return (bool)GetValue(IsDropDownOpenProperty); }
  38. set { SetValue(IsDropDownOpenProperty, BooleanBoxes.Box(value)); }
  39. }
  40. /// <summary>
  41. /// 是否显示分割线
  42. /// </summary>
  43. public bool IsShowSeparator
  44. {
  45. get { return (bool)GetValue(IsShowSeparatorProperty); }
  46. set { SetValue(IsShowSeparatorProperty, BooleanBoxes.Box(value)); }
  47. }
  48. #region menu item
  49. /// <summary>Identifies the <see cref="MenuItemsSource"/> dependency property.</summary>
  50. public static readonly DependencyProperty MenuItemsSourceProperty = DependencyProperty.Register(
  51. nameof(MenuItemsSource), typeof(IEnumerable), typeof(DropDownButton), new PropertyMetadata(null));
  52. /// <summary>
  53. /// Gets or sets an object source used to generate the content of the options.
  54. /// </summary>
  55. public IEnumerable MenuItemsSource
  56. {
  57. get => (IEnumerable)this.GetValue(MenuItemsSourceProperty);
  58. set => this.SetValue(MenuItemsSourceProperty, value);
  59. }
  60. /// <summary>Identifies the <see cref="MenuItemContainerStyle"/> dependency property.</summary>
  61. public static readonly DependencyProperty MenuItemContainerStyleProperty = DependencyProperty.Register(
  62. nameof(MenuItemContainerStyle), typeof(Style), typeof(DropDownButton), new PropertyMetadata(null));
  63. /// <summary>
  64. /// Gets or sets the <see cref="Style"/> used for each item in the options.
  65. /// </summary>
  66. public Style MenuItemContainerStyle
  67. {
  68. get => (Style)this.GetValue(MenuItemContainerStyleProperty);
  69. set => this.SetValue(MenuItemContainerStyleProperty, value);
  70. }
  71. /// <summary>Identifies the <see cref="MenuItemTemplate"/> dependency property.</summary>
  72. public static readonly DependencyProperty MenuItemTemplateProperty = DependencyProperty.Register(
  73. nameof(MenuItemTemplate), typeof(DataTemplate), typeof(DropDownButton), new PropertyMetadata(null));
  74. /// <summary>
  75. /// Gets or sets the <see cref="DataTemplate"/> used to display each item in the options.
  76. /// </summary>
  77. public DataTemplate MenuItemTemplate
  78. {
  79. get => (DataTemplate)this.GetValue(MenuItemTemplateProperty);
  80. set => this.SetValue(MenuItemTemplateProperty, value);
  81. }
  82. /// <summary>Identifies the <see cref="MenuItemTemplateSelector"/> dependency property.</summary>
  83. public static readonly DependencyProperty MenuItemTemplateSelectorProperty = DependencyProperty.Register(
  84. nameof(MenuItemTemplateSelector), typeof(DataTemplateSelector), typeof(DropDownButton), new PropertyMetadata(null));
  85. /// <summary>
  86. /// Gets or sets the <see cref="DataTemplateSelector"/> used to display each item in the options.
  87. /// </summary>
  88. public DataTemplateSelector MenuItemTemplateSelector
  89. {
  90. get => (DataTemplateSelector)this.GetValue(MenuItemTemplateSelectorProperty);
  91. set => this.SetValue(MenuItemTemplateSelectorProperty, value);
  92. }
  93. /// <summary>
  94. /// Gets the collection used to generate the content of the option list.
  95. /// </summary>
  96. /// <exception cref="Exception">
  97. /// Exception thrown if DropDownMenu is not yet defined.
  98. /// </exception>
  99. public ItemCollection MenuItems
  100. {
  101. get
  102. {
  103. if (this.dropDownMenu is null)
  104. {
  105. throw new Exception("DropDownMenu is not defined yet. Please use MenuItemsSource instead.");
  106. }
  107. return this.dropDownMenu.Items;
  108. }
  109. }
  110. #endregion
  111. /// <inheritdoc/>
  112. public override void OnApplyTemplate()
  113. {
  114. base.OnApplyTemplate();
  115. dropDownMenu = GetTemplateChild(DropDownMenuItemName) as MenuItem;
  116. }
  117. }
  118. }