• *C#(WPF)--矩阵拖动和矩阵动画(拖动展开,不足动画效果)


       最近在研发新的项目,遇到了一个桌面模式下的难点--展开动画。之前动画这方面没做过,也许很多人开始做的时候也会遇到相关问题,因此我把几个重点及实际效果图总结展示出来:

       我的开发环境是在VS2017下进行的,这个工具条主要功能是:一个工具条,可进行拖拉。可进行拖拉展开,可在拖动之后不足展开并反向继续展开剩下的部分;

      一、【拖动】   拖动的核心代码是通过矩阵进行定位和拖动的,定位是以父容器为模板的。以下是核心代码(及效果图):

               

     1         /// <summary>
     2         ///  这里TitleBar代指最顶上的操作Bar
     3         ///  桌面模式下默认展开工具栏-动画
     4         /// </summary>
     5         private void DesktopToolWindowClick()
     6         {
     7 
     8 
     9             //添加行为
    10             var behaviors = System.Windows.Interactivity.Interaction.GetBehaviors(this);
    11             behaviors.Clear();
    12 
    13             behaviors = System.Windows.Interactivity.Interaction.GetBehaviors(this);
    14             behaviors.Clear();
    15 
    16 
    17             //添加拖拉事件
    18             this._OnMouse = new MoveInContainerBehavior(MoveInContainerBehavior.MoveModes.Free, new Rect(0, 0, WindowsWidth, WindowsHeight));
    19             behaviors.Add(this._OnMouse);
    20         }
    21 
    22         /// <summary>
    23         /// 加载用户控件的时候订阅事件
    24         /// </summary>
    25         private void _OnRegisterUserControl()
    26         {
    27 
    28             //订阅鼠标按下控件的事件;
    29             _OnMouse.MouseLeftButtonDown += new MoveInContainerBehavior.MouseLeftButtonDownEventHandler(_OnMouseDownEvent);
    30             //订阅鼠标拖动控件的事件;
    31             _OnMouse.MouseMove += new MoveInContainerBehavior.MouseMoveEventHandler(_OnMouseMoveEvent);
    32             //订阅鼠标释放控件的事件;
    33             _OnMouse.MouseLeftButtonUp += new MoveInContainerBehavior.MouseLeftButtonUpEventHandler(_OnMouseReleseEvent);
    34 
    35         }
    36 
    37         /// <summary>
    38         /// 用该事件控制弹窗位置
    39         /// </summary>
    40         /// <param name="sender"></param>
    41         /// <param name="e"></param>
    42         private void _ToolBar_Opened(object sender, EventArgs e)
    43         {
    44             //计算出控件移动的距离
    45             var Windows_Lengh = _UserControl_XEnd + this.PopMenu.ActualWidth;
    46             if (this._UserControl.ActualWidth + Windows_Lengh >= WindowsWidth)
    47             {
    48                 this._ToolBar.Placement = System.Windows.Controls.Primitives.PlacementMode.Left;
    49                 this._ToolBar.HorizontalOffset = -5;
    50             }
    51             else
    52             {
    53                 this._ToolBar.Placement = System.Windows.Controls.Primitives.PlacementMode.Right;
    54                 this._ToolBar.HorizontalOffset = 5;
    55             }
    56         }

      二、【拖拉改变样式】 通过样式库调用可以在动画开始的时候就更换主题样式通过backup更改样式而不是UI直接改变,以下是核心代码(及效果图):

              

     1         #region 更改样式为【展开时候的样式】
     2             this._GridMain.Margin = new Thickness(0, -46, 0, 0);
     3             this._GridRowsF.Height = new GridLength(47);
     4             this.TitleBar.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#4a94ff"));
     5             this.TitleBar.Opacity = 1;
     6             this.TitleBar.Margin = new Thickness(-7, -3, -7, 0);
     7             this.Circle_Bar.Stroke = Brushes.White;
     8             this.Circle_Bar.Margin = new Thickness(0, -3, 0, 0);
     9             this._UserControl.Style = this.FindResource("Style.UserControl.PresentationMode.Desktop.Expand.UserControlStyles") as Style;
    10             #endregion

      三、【拖拉展开-边缘充足】 进行一个动画 那就是直接按照自定义的动画时间进行展开,以下是核心代码(及效果图)使用GridLengthAnimation动画类自行百度,下面是经过二次编译的类调用方法

     1             #region 尝试展开工具条--向下展开
     2             GridLengthAnimation ExpandAnimate = new GridLengthAnimation();
     3             ExpandAnimate.From = new GridLength(0, GridUnitType.Pixel);
     4             ExpandAnimate.To = new GridLength(_GridRowsSLength, GridUnitType.Pixel);
     5             ExpandAnimate.Duration = TimeSpan.FromSeconds(0.3);
     6             ExpandAnimate.AutoReverse = false;
     7             this._GridMain.RowDefinitions[1].BeginAnimation(RowDefinition.HeightProperty, ExpandAnimate);
     8 
     9 
    10 
    11 
    12             #endregion

      四、【拖拉展开-边缘不足】 进行两个动画 1-先展开到边缘动画  2-再反弹反方向展开动画,以下是核心代码(及效果图):

     1  #region 先往下展开,展开结束之后再启用往上增加动画
     2             GridLengthAnimation ExpandAnimate = new GridLengthAnimation();
     3             ExpandAnimate.From = new GridLength(0, GridUnitType.Pixel);
     4             ExpandAnimate.To = new GridLength(WindowsHeight - ParentPoint.Y - 68, GridUnitType.Pixel);
     5             ExpandAnimate.Duration = TimeSpan.FromSeconds(0.15);
     6             ExpandAnimate.AutoReverse = false;
     7             ExpandAnimate.Completed += StartMatrixExpandAnimate_Completed;
     8             this._GridMain.RowDefinitions[1].BeginAnimation(RowDefinition.HeightProperty, ExpandAnimate);
     9 
    10             #endregion
    11 
    12  /// <summary>
    13         /// 当展开动画结束之后开始执行反向动画
    14         /// </summary>
    15         /// <param name="sender"></param>
    16         /// <param name="e"></param>
    17         private void StartMatrixExpandAnimate_Completed(object sender, EventArgs e)
    18         {
    19             //删除动画
    20             this._GridMain.RowDefinitions[1].BeginAnimation(RowDefinition.HeightProperty, null);
    21 
    22             #region 向上移动动画
    23             // 1-向上移动
    24             Storyboard storyboard = new Storyboard();
    25             storyboard.FillBehavior = FillBehavior.Stop;
    26             MatrixTransform matrixTransformOfOwner = this.RenderTransform as MatrixTransform;
    27             if (matrixTransformOfOwner == null)
    28             {
    29                 matrixTransformOfOwner = new MatrixTransform(this.RenderTransform.Value);
    30                 this.RenderTransform = matrixTransformOfOwner;
    31             }
    32             this._oldTransform = this.RenderTransform;
    33             Matrix matrixOfOwner = this.RenderTransform.Value;
    34             Matrix fromMatrix = matrixOfOwner;
    35             Matrix toMatrix = new Matrix();
    36             toMatrix.OffsetX = ParentPoint.X;
    37             toMatrix.OffsetY = WindowsHeight - _GridRowsSLength - 68;
    38 
    39             MatrixAnimation matrixAnimation = new MatrixAnimation(fromMatrix, toMatrix, TimeSpan.FromSeconds(0.3));
    40             matrixAnimation.Completed += (s, ex) => { UnlockProperty(toMatrix); };
    41 
    42             Storyboard.SetTarget(matrixAnimation, this);
    43             Storyboard.SetTargetProperty(matrixAnimation, new PropertyPath("(UIElement.RenderTransform).(MatrixTransform.Matrix)"));
    44 
    45             storyboard.Children.Add(matrixAnimation);
    46             storyboard.Begin();
    47 
    48             #endregion
    49 
    50 
    51 
    52         }

      五、【拖拉展开-到达边缘时】进行一个动画 反弹反方向展开动画,类似【四】 直接上效果图就不贴代码了。

                       

        本文暂时不展示提供Demo下载,提供一个思路供大家参考。

  • 相关阅读:
    0125——时钟
    0125——动画2
    0124——动画1
    0124——KVC KVO模式
    0123——单例模式
    0122——简单小动画+微博简单模拟2
    0122——UITabBarController
    0119——UIImageView的一些属性 和 简单动画实现
    12月28号 ios设计简单操作
    12月25号 Category类别
  • 原文地址:https://www.cnblogs.com/BarryJames/p/7542720.html
Copyright © 2020-2023  润新知