ToggleBlock.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using System.ComponentModel;
  2. using System.Linq;
  3. using System.Windows;
  4. using System.Windows.Controls;
  5. using System.Windows.Input;
  6. using System.Windows.Markup;
  7. using HandyControl.Data;
  8. using HandyControl.Input;
  9. using HandyControl.Interactivity;
  10. namespace HandyControl.Controls;
  11. /// <summary>
  12. /// 切换块
  13. /// </summary>
  14. public class ToggleBlock : Control
  15. {
  16. public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register(nameof(IsChecked), typeof(bool?), typeof(ToggleBlock), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal));
  17. public static readonly DependencyProperty CheckedContentProperty = DependencyProperty.Register(nameof(CheckedContent), typeof(object), typeof(ToggleBlock), new PropertyMetadata(default(object)));
  18. public static readonly DependencyProperty UnCheckedContentProperty = DependencyProperty.Register(nameof(UnCheckedContent), typeof(object), typeof(ToggleBlock), new PropertyMetadata(default(object)));
  19. public static readonly DependencyProperty IndeterminateContentProperty = DependencyProperty.Register(nameof(IndeterminateContent), typeof(object), typeof(ToggleBlock), new PropertyMetadata(default(object)));
  20. public static readonly DependencyProperty ToggleGestureProperty = DependencyProperty.Register(nameof(ToggleGesture), typeof(MouseGesture), typeof(ToggleBlock), new UIPropertyMetadata(new MouseGesture(MouseAction.None), OnToggleGestureChanged));
  21. [Category("Appearance")]
  22. [TypeConverter(typeof(NullableBoolConverter))]
  23. [Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)]
  24. public bool? IsChecked
  25. {
  26. get
  27. {
  28. // Because Nullable<bool> unboxing is very slow (uses reflection) first we cast to bool
  29. var value = GetValue(IsCheckedProperty);
  30. // ReSharper disable once RedundantExplicitNullableCreation
  31. return value == null ? new bool?() : new bool?((bool) value);
  32. }
  33. set => SetValue(IsCheckedProperty, value.HasValue ? ValueBoxes.BooleanBox(value.Value) : null);
  34. }
  35. public object CheckedContent
  36. {
  37. get => GetValue(CheckedContentProperty);
  38. set => SetValue(CheckedContentProperty, value);
  39. }
  40. public object UnCheckedContent
  41. {
  42. get => GetValue(UnCheckedContentProperty);
  43. set => SetValue(UnCheckedContentProperty, value);
  44. }
  45. public object IndeterminateContent
  46. {
  47. get => GetValue(IndeterminateContentProperty);
  48. set => SetValue(IndeterminateContentProperty, value);
  49. }
  50. [ValueSerializer(typeof(MouseGestureValueSerializer))]
  51. [TypeConverter(typeof(MouseGestureConverter))]
  52. public MouseGesture ToggleGesture
  53. {
  54. get => (MouseGesture) GetValue(ToggleGestureProperty);
  55. set => SetValue(ToggleGestureProperty, value);
  56. }
  57. public ToggleBlock()
  58. {
  59. CommandBindings.Add(new CommandBinding(ControlCommands.Toggle, OnToggled));
  60. OnToggleGestureChanged(ToggleGesture);
  61. }
  62. private static void OnToggleGestureChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  63. {
  64. ((ToggleBlock) d).OnToggleGestureChanged((MouseGesture) e.NewValue);
  65. }
  66. private void OnToggleGestureChanged(MouseGesture newValue)
  67. {
  68. foreach (var binding in InputBindings.OfType<SimpleMouseBinding>().ToList())
  69. {
  70. InputBindings.Remove(binding);
  71. }
  72. InputBindings.Add(new SimpleMouseBinding(ControlCommands.Toggle, newValue));
  73. }
  74. private void OnToggled(object sender, ExecutedRoutedEventArgs e)
  75. {
  76. SetCurrentValue(IsCheckedProperty, IsChecked == true ? ValueBoxes.FalseBox : ValueBoxes.TrueBox);
  77. }
  78. }