TransitioningContentControl.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System.Windows;
  2. using System.Windows.Controls;
  3. using System.Windows.Media;
  4. using System.Windows.Media.Animation;
  5. using HandyControl.Data;
  6. using HandyControl.Tools;
  7. namespace HandyControl.Controls;
  8. public class TransitioningContentControl : ContentControl
  9. {
  10. private FrameworkElement _contentPresenter;
  11. private static Storyboard StoryboardBuildInDefault;
  12. private Storyboard _storyboardBuildIn;
  13. public TransitioningContentControl()
  14. {
  15. Loaded += TransitioningContentControl_Loaded;
  16. Unloaded += TransitioningContentControl_Unloaded;
  17. }
  18. public static readonly DependencyProperty TransitionModeProperty = DependencyProperty.Register(
  19. nameof(TransitionMode), typeof(TransitionMode), typeof(TransitioningContentControl), new PropertyMetadata(default(TransitionMode), OnTransitionModeChanged));
  20. private static void OnTransitionModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  21. {
  22. var ctl = (TransitioningContentControl) d;
  23. ctl.OnTransitionModeChanged((TransitionMode) e.NewValue);
  24. }
  25. private void OnTransitionModeChanged(TransitionMode newValue)
  26. {
  27. _storyboardBuildIn = ResourceHelper.GetResourceInternal<Storyboard>($"{newValue}Transition");
  28. StartTransition();
  29. }
  30. public TransitionMode TransitionMode
  31. {
  32. get => (TransitionMode) GetValue(TransitionModeProperty);
  33. set => SetValue(TransitionModeProperty, value);
  34. }
  35. public static readonly DependencyProperty TransitionStoryboardProperty = DependencyProperty.Register(
  36. nameof(TransitionStoryboard), typeof(Storyboard), typeof(TransitioningContentControl), new PropertyMetadata(default(Storyboard)));
  37. public Storyboard TransitionStoryboard
  38. {
  39. get => (Storyboard) GetValue(TransitionStoryboardProperty);
  40. set => SetValue(TransitionStoryboardProperty, value);
  41. }
  42. private void TransitioningContentControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) => StartTransition();
  43. private void TransitioningContentControl_Loaded(object sender, RoutedEventArgs e)
  44. {
  45. IsVisibleChanged += TransitioningContentControl_IsVisibleChanged;
  46. }
  47. private void TransitioningContentControl_Unloaded(object sender, RoutedEventArgs e)
  48. {
  49. IsVisibleChanged -= TransitioningContentControl_IsVisibleChanged;
  50. }
  51. private void StartTransition()
  52. {
  53. if (_contentPresenter == null || !IsVisible) return;
  54. if (TransitionStoryboard != null)
  55. {
  56. TransitionStoryboard.Begin(_contentPresenter);
  57. }
  58. else if (_storyboardBuildIn != null)
  59. {
  60. _storyboardBuildIn?.Begin(_contentPresenter);
  61. }
  62. else
  63. {
  64. StoryboardBuildInDefault ??= ResourceHelper.GetResourceInternal<Storyboard>($"{default(TransitionMode)}Transition");
  65. StoryboardBuildInDefault?.Begin(_contentPresenter);
  66. }
  67. }
  68. public override void OnApplyTemplate()
  69. {
  70. base.OnApplyTemplate();
  71. _contentPresenter = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
  72. if (_contentPresenter != null)
  73. {
  74. _contentPresenter.RenderTransformOrigin = new Point(0.5, 0.5);
  75. _contentPresenter.RenderTransform = new TransformGroup
  76. {
  77. Children =
  78. {
  79. new ScaleTransform(),
  80. new SkewTransform(),
  81. new RotateTransform(),
  82. new TranslateTransform()
  83. }
  84. };
  85. }
  86. StartTransition();
  87. }
  88. protected override void OnContentChanged(object oldContent, object newContent)
  89. {
  90. base.OnContentChanged(oldContent, newContent);
  91. if (newContent is null)
  92. {
  93. return;
  94. }
  95. StartTransition();
  96. }
  97. }