From fb3ec79c1cb770173e360ad83b6fe3d5973aa52b Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Tue, 26 Nov 2019 00:48:08 +0800 Subject: [PATCH] add Drawer --- README.md | 8 +- .../Data/SideMenuConfig.json | 120 ++++++++ .../UserControl/Controls/DrawerDemoCtl.xaml | 12 +- .../Controls/Other/Drawer.cs | 267 ++++++++++++------ 4 files changed, 308 insertions(+), 99 deletions(-) create mode 100644 src/Shared/HandyControlDemo_Shared/Data/SideMenuConfig.json diff --git a/README.md b/README.md index 200dc3e8..6e820dfc 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,10 @@ Step 4:enjoy coding ## Latest examples +### Drawer + +![Drawer](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/Drawer.gif) + ### Poptip ![Poptip](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/Poptip.gif) @@ -102,12 +106,12 @@ Step 4:enjoy coding ![SplitButton](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/SplitButton.png) +## History publication + ### FloatingBlock ![FloatingBlock](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/FloatingBlock.gif) -## History publication - ### HoneycombPanel ![HoneycombPanel](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/HoneycombPanel.png) diff --git a/src/Shared/HandyControlDemo_Shared/Data/SideMenuConfig.json b/src/Shared/HandyControlDemo_Shared/Data/SideMenuConfig.json new file mode 100644 index 00000000..8e58a2ac --- /dev/null +++ b/src/Shared/HandyControlDemo_Shared/Data/SideMenuConfig.json @@ -0,0 +1,120 @@ +[ + { + "Header": "Overview", + "IconKey": "/HandyControlDemo;component/Resources/Img/DevOps/DevOps-Overview.png", + "Items": [ + { + "Header": "Summary", + "IconKey": "" + }, + { + "Header": "Dashboards", + "IconKey": "" + }, + { + "Header": "Wiki", + "IconKey": "" + } + ] + }, + { + "Header": "Boards", + "IconKey": "/HandyControlDemo;component/Resources/Img/DevOps/DevOps-Boards.png", + "Items": [ + { + "Header": "Work Items", + "IconKey": "" + }, + { + "Header": "Boards", + "IconKey": "" + }, + { + "Header": "Backlogs", + "IconKey": "" + }, + { + "Header": "Sprints", + "IconKey": "" + }, + { + "Header": "Queries", + "IconKey": "" + } + ] + }, + { + "Header": "Repos", + "IconKey": "/HandyControlDemo;component/Resources/Img/DevOps/DevOps-Repos.png", + "Items": [ + { + "Header": "Files", + "IconKey": "" + }, + { + "Header": "Commits", + "IconKey": "" + }, + { + "Header": "Pushes", + "IconKey": "" + }, + { + "Header": "Branches", + "IconKey": "" + }, + { + "Header": "Tags", + "IconKey": "" + }, + { + "Header": "Pull requests", + "IconKey": "" + } + ] + }, + { + "Header": "Pipelines", + "IconKey": "/HandyControlDemo;component/Resources/Img/DevOps/DevOps-Pipelines.png", + "Items": [ + { + "Header": "Builds", + "IconKey": "" + }, + { + "Header": "Releases", + "IconKey": "" + }, + { + "Header": "Library", + "IconKey": "" + }, + { + "Header": "Task groups", + "IconKey": "" + }, + { + "Header": "Deployment groups", + "IconKey": "" + } + ] + }, + { + "Header": "Test Plans", + "IconKey": "/HandyControlDemo;component/Resources/Img/DevOps/DevOps-TestPlans.png", + "Items": [ + { + "Header": "Test Plans", + "IconKey": "" + }, + { + "Header": "Runs", + "IconKey": "" + }, + { + "Header": "Load test", + "IconKey": "" + } + ] + } +] \ No newline at end of file diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/DrawerDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/DrawerDemoCtl.xaml index d637c9a5..3da2d201 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/DrawerDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/DrawerDemoCtl.xaml @@ -21,7 +21,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -45,8 +45,8 @@ - - + + @@ -57,8 +57,8 @@ - - + + diff --git a/src/Shared/HandyControl_Shared/Controls/Other/Drawer.cs b/src/Shared/HandyControl_Shared/Controls/Other/Drawer.cs index ba71e131..c99d5e16 100644 --- a/src/Shared/HandyControl_Shared/Controls/Other/Drawer.cs +++ b/src/Shared/HandyControl_Shared/Controls/Other/Drawer.cs @@ -5,6 +5,7 @@ using System.Windows.Documents; using System.Windows.Input; using System.Windows.Markup; using System.Windows.Media; +using System.Windows.Media.Animation; using HandyControl.Data; using HandyControl.Interactivity; using HandyControl.Tools; @@ -14,20 +15,28 @@ namespace HandyControl.Controls [ContentProperty("Content")] public class Drawer : FrameworkElement { + private Storyboard _storyboard; + private AdornerContainer _container; - private ContentControl _animateControl; + private ContentControl _animationControl; private TranslateTransform _translateTransform; private double _animationLength; - private DependencyProperty _animationProperty; + private string _animationPropertyName; private FrameworkElement _maskElement; private AdornerLayer _layer; + private System.Windows.Window _window; + + private UIElement _windowContentElement; + + private Point _contentRenderTransformOrigin; + public Drawer() { Loaded += Drawer_Loaded; @@ -47,10 +56,16 @@ namespace HandyControl.Controls private void Drawer_Unloaded(object sender, RoutedEventArgs e) { Loaded -= Drawer_Loaded; + if (_maskElement != null) { _maskElement.PreviewMouseLeftButtonDown -= MaskElement_PreviewMouseLeftButtonDown; } + + if (_storyboard != null) + { + _storyboard.Completed -= Storyboard_Completed; + } } public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register( @@ -122,88 +137,19 @@ namespace HandyControl.Controls set => SetValue(ContentProperty, value); } - private void OnIsOpenChanged(bool isOpen) - { - if (Content == null) return; - - var window = WindowHelper.GetActiveWindow(); - if (window == null) return; - - var decorator = VisualHelper.GetChild(window); - _layer = decorator?.AdornerLayer; - if (_layer == null) return; - - if (_container == null) - { - CreateContainer(); - } - - switch (ShowMode) - { - case DrawerShowMode.Cover: - ShowByCover(isOpen); - break; - case DrawerShowMode.Push: - ShowByPush(isOpen); - break; - case DrawerShowMode.Press: - ShowByPress(isOpen); - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - private void ShowByCover(bool isOpen) - { - if (isOpen) - { - _maskElement?.BeginAnimation(OpacityProperty, AnimationHelper.CreateAnimation(1)); - _translateTransform.BeginAnimation(_animationProperty, AnimationHelper.CreateAnimation(0)); - _layer.Add(_container); - } - else - { - var animation = AnimationHelper.CreateAnimation(_animationLength); - animation.Completed += (s, e) => _layer.Remove(_container); - _maskElement?.BeginAnimation(OpacityProperty, AnimationHelper.CreateAnimation(0)); - _translateTransform.BeginAnimation(_animationProperty, animation); - } - } - - private void ShowByPush(bool isOpen) - { - if (isOpen) - { - - } - else - { - - } - } - - private void ShowByPress(bool isOpen) - { - if (isOpen) - { - - } - else - { - - } - } - private void CreateContainer() { + _storyboard = new Storyboard(); + _storyboard.Completed += Storyboard_Completed; + _translateTransform = new TranslateTransform(); - _animateControl = new ContentControl + _animationControl = new ContentControl { Content = Content, RenderTransform = _translateTransform, DataContext = this }; + var panel = new SimplePanel { ClipToBounds = true @@ -220,44 +166,44 @@ namespace HandyControl.Controls panel.Children.Add(_maskElement); } - _animateControl.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); - var size = _animateControl.DesiredSize; + _animationControl.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); + var size = _animationControl.DesiredSize; switch (Dock) { case Dock.Left: - _animateControl.HorizontalAlignment = HorizontalAlignment.Left; - _animateControl.VerticalAlignment = VerticalAlignment.Stretch; + _animationControl.HorizontalAlignment = HorizontalAlignment.Left; + _animationControl.VerticalAlignment = VerticalAlignment.Stretch; _translateTransform.X = -size.Width; _animationLength = -size.Width; - _animationProperty = TranslateTransform.XProperty; + _animationPropertyName = "(UIElement.RenderTransform).(TranslateTransform.X)"; break; case Dock.Top: - _animateControl.HorizontalAlignment = HorizontalAlignment.Stretch; - _animateControl.VerticalAlignment = VerticalAlignment.Top; + _animationControl.HorizontalAlignment = HorizontalAlignment.Stretch; + _animationControl.VerticalAlignment = VerticalAlignment.Top; _translateTransform.Y = -size.Height; _animationLength = -size.Height; - _animationProperty = TranslateTransform.YProperty; + _animationPropertyName = "(UIElement.RenderTransform).(TranslateTransform.Y)"; break; case Dock.Right: - _animateControl.HorizontalAlignment = HorizontalAlignment.Right; - _animateControl.VerticalAlignment = VerticalAlignment.Stretch; + _animationControl.HorizontalAlignment = HorizontalAlignment.Right; + _animationControl.VerticalAlignment = VerticalAlignment.Stretch; _translateTransform.X = size.Width; _animationLength = size.Width; - _animationProperty = TranslateTransform.XProperty; + _animationPropertyName = "(UIElement.RenderTransform).(TranslateTransform.X)"; break; case Dock.Bottom: - _animateControl.HorizontalAlignment = HorizontalAlignment.Stretch; - _animateControl.VerticalAlignment = VerticalAlignment.Bottom; + _animationControl.HorizontalAlignment = HorizontalAlignment.Stretch; + _animationControl.VerticalAlignment = VerticalAlignment.Bottom; _translateTransform.Y = size.Height; _animationLength = size.Height; - _animationProperty = TranslateTransform.YProperty; + _animationPropertyName = "(UIElement.RenderTransform).(TranslateTransform.Y)"; break; default: throw new ArgumentOutOfRangeException(); } - panel.Children.Add(_animateControl); + panel.Children.Add(_animationControl); _container = new AdornerContainer(_layer) { Child = panel, @@ -265,6 +211,145 @@ namespace HandyControl.Controls }; } + private void Storyboard_Completed(object sender, EventArgs e) + { + if (!IsOpen) + { + _windowContentElement.SetCurrentValue(RenderTransformOriginProperty, _contentRenderTransformOrigin); + _layer.Remove(_container); + } + } + + private void OnIsOpenChanged(bool isOpen) + { + if (Content == null) return; + + _window = WindowHelper.GetActiveWindow(); + if (_window == null) return; + + _windowContentElement = _window.Content as UIElement; + if (_windowContentElement == null) return; + + _contentRenderTransformOrigin = _windowContentElement.RenderTransformOrigin; + + var decorator = VisualHelper.GetChild(_window); + _layer = decorator?.AdornerLayer; + if (_layer == null) return; + + if (_container == null) + { + CreateContainer(); + } + + switch (ShowMode) + { + case DrawerShowMode.Push: + ShowByPush(isOpen); + break; + case DrawerShowMode.Press: + _windowContentElement.SetCurrentValue(RenderTransformOriginProperty, new Point(0.5, 0.5)); + ShowByPress(isOpen); + break; + } + + if (isOpen) + { + if (_maskElement != null) + { + var maskAnimation = AnimationHelper.CreateAnimation(1); + Storyboard.SetTarget(maskAnimation, _maskElement); + Storyboard.SetTargetProperty(maskAnimation, new PropertyPath(OpacityProperty.Name)); + _storyboard.Children.Add(maskAnimation); + } + + var drawerAnimation = AnimationHelper.CreateAnimation(0); + Storyboard.SetTarget(drawerAnimation, _animationControl); + Storyboard.SetTargetProperty(drawerAnimation, new PropertyPath(_animationPropertyName)); + _storyboard.Children.Add(drawerAnimation); + _layer.Remove(_container); + _layer.Add(_container); + } + else + { + if (_maskElement != null) + { + var maskAnimation = AnimationHelper.CreateAnimation(0); + Storyboard.SetTarget(maskAnimation, _maskElement); + Storyboard.SetTargetProperty(maskAnimation, new PropertyPath(OpacityProperty.Name)); + _storyboard.Children.Add(maskAnimation); + } + + var drawerAnimation = AnimationHelper.CreateAnimation(_animationLength); + Storyboard.SetTarget(drawerAnimation, _animationControl); + Storyboard.SetTargetProperty(drawerAnimation, new PropertyPath(_animationPropertyName)); + _storyboard.Children.Add(drawerAnimation); + } + + _storyboard.Begin(); + } + + private void ShowByPush(bool isOpen) + { + string animationPropertyName; + + switch (Dock) + { + case Dock.Left: + case Dock.Right: + animationPropertyName = "(UIElement.RenderTransform).(TranslateTransform.X)"; + _windowContentElement.RenderTransform = new TranslateTransform + { + X = isOpen ? 0 : -_animationLength + }; + break; + case Dock.Top: + case Dock.Bottom: + animationPropertyName = "(UIElement.RenderTransform).(TranslateTransform.Y)"; + _windowContentElement.RenderTransform = new TranslateTransform + { + Y = isOpen ? 0 : -_animationLength + }; + break; + default: + throw new ArgumentOutOfRangeException(); + } + + var animation = isOpen + ? AnimationHelper.CreateAnimation(-_animationLength) + : AnimationHelper.CreateAnimation(0); + Storyboard.SetTarget(animation, _windowContentElement); + Storyboard.SetTargetProperty(animation, new PropertyPath(animationPropertyName)); + + _storyboard.Children.Add(animation); + } + + private void ShowByPress(bool isOpen) + { + _windowContentElement.RenderTransform = isOpen + ? new ScaleTransform() + : new ScaleTransform + { + ScaleX = 0.9, + ScaleY = 0.9 + }; + + var animationX = isOpen + ? AnimationHelper.CreateAnimation(.9) + : AnimationHelper.CreateAnimation(1); + Storyboard.SetTarget(animationX, _windowContentElement); + Storyboard.SetTargetProperty(animationX, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleX)")); + + _storyboard.Children.Add(animationX); + + var animationY = isOpen + ? AnimationHelper.CreateAnimation(.9) + : AnimationHelper.CreateAnimation(1); + Storyboard.SetTarget(animationY, _windowContentElement); + Storyboard.SetTargetProperty(animationY, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)")); + + _storyboard.Children.Add(animationY); + } + private void MaskElement_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (MaskCanClose)