1. 程式人生 > >*C#(WPF)--矩陣拖動和矩陣動畫(拖動展開,不足動畫效果)

*C#(WPF)--矩陣拖動和矩陣動畫(拖動展開,不足動畫效果)

stop 項目 鼠標 ani sys unlock 控件移動 top art

最近在研發新的項目,遇到了一個桌面模式下的難點--展開動畫。之前動畫這方面沒做過,也許很多人開始做的時候也會遇到相關問題,因此我把幾個重點及實際效果圖總結展示出來:

我的開發環境是在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下載,提供一個思路供大家參考。

*C#(WPF)--矩陣拖動和矩陣動畫(拖動展開,不足動畫效果)