Decorator.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright (c) The Perspex Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using Perspex.Metadata;
  4. namespace Perspex.Controls
  5. {
  6. /// <summary>
  7. /// Base class for controls which decorate a single child control.
  8. /// </summary>
  9. public class Decorator : Control
  10. {
  11. /// <summary>
  12. /// Defines the <see cref="Child"/> property.
  13. /// </summary>
  14. public static readonly StyledProperty<Control> ChildProperty =
  15. PerspexProperty.Register<Decorator, Control>(nameof(Child));
  16. /// <summary>
  17. /// Defines the <see cref="Padding"/> property.
  18. /// </summary>
  19. public static readonly StyledProperty<Thickness> PaddingProperty =
  20. PerspexProperty.Register<Decorator, Thickness>(nameof(Padding));
  21. /// <summary>
  22. /// Initializes static members of the <see cref="Decorator"/> class.
  23. /// </summary>
  24. static Decorator()
  25. {
  26. ChildProperty.Changed.AddClassHandler<Decorator>(x => x.ChildChanged);
  27. }
  28. /// <summary>
  29. /// Gets or sets the decorated control.
  30. /// </summary>
  31. [Content]
  32. public Control Child
  33. {
  34. get { return GetValue(ChildProperty); }
  35. set { SetValue(ChildProperty, value); }
  36. }
  37. /// <summary>
  38. /// Gets or sets the padding to place around the <see cref="Child"/> control.
  39. /// </summary>
  40. public Thickness Padding
  41. {
  42. get { return GetValue(PaddingProperty); }
  43. set { SetValue(PaddingProperty, value); }
  44. }
  45. /// <inheritdoc/>
  46. protected override Size MeasureOverride(Size availableSize)
  47. {
  48. var content = Child;
  49. var padding = Padding;
  50. if (content != null)
  51. {
  52. content.Measure(availableSize.Deflate(padding));
  53. return content.DesiredSize.Inflate(padding);
  54. }
  55. else
  56. {
  57. return new Size(padding.Left + padding.Right, padding.Bottom + padding.Top);
  58. }
  59. }
  60. /// <inheritdoc/>
  61. protected override Size ArrangeOverride(Size finalSize)
  62. {
  63. Control content = Child;
  64. content?.Arrange(new Rect(finalSize).Deflate(Padding));
  65. return finalSize;
  66. }
  67. /// <summary>
  68. /// Called when the <see cref="Child"/> property changes.
  69. /// </summary>
  70. /// <param name="e">The event args.</param>
  71. private void ChildChanged(PerspexPropertyChangedEventArgs e)
  72. {
  73. var oldChild = (Control)e.OldValue;
  74. var newChild = (Control)e.NewValue;
  75. if (oldChild != null)
  76. {
  77. ((ISetLogicalParent)oldChild).SetParent(null);
  78. LogicalChildren.Clear();
  79. VisualChildren.Remove(oldChild);
  80. }
  81. if (newChild != null)
  82. {
  83. ((ISetLogicalParent)newChild).SetParent(this);
  84. VisualChildren.Add(newChild);
  85. LogicalChildren.Add(newChild);
  86. }
  87. }
  88. }
  89. }