AdornerElement.cs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using System;
  2. using System.ComponentModel;
  3. using System.Windows;
  4. using System.Windows.Controls;
  5. using HandyControl.Data;
  6. namespace HandyControl.Controls;
  7. public abstract class AdornerElement : Control, IDisposable
  8. {
  9. protected FrameworkElement ElementTarget { get; set; }
  10. public static readonly DependencyProperty TargetProperty = DependencyProperty.Register(
  11. nameof(Target), typeof(FrameworkElement), typeof(AdornerElement), new PropertyMetadata(default(FrameworkElement), OnTargetChanged));
  12. private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  13. {
  14. var ctl = (AdornerElement) d;
  15. ctl.OnTargetChanged(ctl.ElementTarget, false);
  16. ctl.OnTargetChanged((FrameworkElement) e.NewValue, true);
  17. }
  18. [Bindable(true), Category("Layout")]
  19. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  20. public FrameworkElement Target
  21. {
  22. get => (FrameworkElement) GetValue(TargetProperty);
  23. set => SetValue(TargetProperty, value);
  24. }
  25. public static readonly DependencyProperty InstanceProperty = DependencyProperty.RegisterAttached(
  26. "Instance", typeof(AdornerElement), typeof(AdornerElement), new PropertyMetadata(default(AdornerElement), OnInstanceChanged));
  27. private static void OnInstanceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  28. {
  29. if (d is not FrameworkElement target) return;
  30. var element = (AdornerElement) e.NewValue;
  31. element.OnInstanceChanged(target);
  32. }
  33. protected virtual void OnInstanceChanged(FrameworkElement target) => Target = target;
  34. public static void SetInstance(DependencyObject element, AdornerElement value)
  35. => element.SetValue(InstanceProperty, value);
  36. public static AdornerElement GetInstance(DependencyObject element)
  37. => (AdornerElement) element.GetValue(InstanceProperty);
  38. public static readonly DependencyProperty IsInstanceProperty = DependencyProperty.RegisterAttached(
  39. "IsInstance", typeof(bool), typeof(AdornerElement), new PropertyMetadata(ValueBoxes.TrueBox));
  40. public static void SetIsInstance(DependencyObject element, bool value)
  41. => element.SetValue(IsInstanceProperty, ValueBoxes.BooleanBox(value));
  42. public static bool GetIsInstance(DependencyObject element)
  43. => (bool) element.GetValue(IsInstanceProperty);
  44. protected virtual void OnTargetChanged(FrameworkElement element, bool isNew)
  45. {
  46. if (element == null) return;
  47. if (!isNew)
  48. {
  49. element.Unloaded -= TargetElement_Unloaded;
  50. ElementTarget = null;
  51. }
  52. else
  53. {
  54. element.Unloaded += TargetElement_Unloaded;
  55. ElementTarget = element;
  56. }
  57. }
  58. private void TargetElement_Unloaded(object sender, RoutedEventArgs e)
  59. {
  60. if (sender is FrameworkElement element)
  61. {
  62. element.Unloaded -= TargetElement_Unloaded;
  63. Dispose();
  64. }
  65. }
  66. protected abstract void Dispose();
  67. void IDisposable.Dispose() => Dispose();
  68. }