WPF之Manipulation


需求:現,在窗口下有一個StackPanel控件.

  1.可以拖動.

  2.可以展開及收縮(不僅僅可以拖動還可以點擊)

  3.窗口向坐標軸一樣分四個象限,在不同的區域停靠在不同的地方(四個角).

 

第一階段:

  我遇到的問題:

  1.起初完成的時候發現StackPanel拖動的時候一直發瘋一樣的抖,

   解決方法:ManipulationStarting事件中,e.ManipulationContainer = this.myGrid,容器要父控件,我原先寫成自己本身了.

  2.為啥寫了之后觸控點不動?

   解決發發:查看構造函數中myStackPanel.RenderTransform = new MatrixTransform(),但是這樣做會給后面留下新的問題,花了我一天時間找出這處.后面詳述.

 1 Xaml's code:
 2 
 3 <Window x:Class="LearnWpf.ManipulationDemo"
 4         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 5         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 6         Title="ManipulationDemo" Height="300" Width="300">
 7     <Grid x:Name="myGrid">
 8         <StackPanel x:Name="myStackPanel"
 9                     Background="Red" Height="50" Width="50"
10                     ManipulationStarting="StackPanel_ManipulationStarting"
11                     ManipulationDelta="StackPanel_ManipulationDelta"
12                     ManipulationCompleted="StackPanel_ManipulationCompleted"
13                     />
14     </Grid>
15 </Window>
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Windows;
 6 using System.Windows.Controls;
 7 using System.Windows.Data;
 8 using System.Windows.Documents;
 9 using System.Windows.Input;
10 using System.Windows.Media;
11 using System.Windows.Media.Imaging;
12 using System.Windows.Shapes;
13 
14 namespace LearnWpf
15 {
16     /// <summary>
17     /// ManipulationDemo.xaml 的交互邏輯
18     /// </summary>
19     public partial class ManipulationDemo : Window
20     {
21         public ManipulationDemo()
22         {
23             InitializeComponent();
24             myStackPanel.RenderTransform = new MatrixTransform();
25             myStackPanel.IsManipulationEnabled = true;
26         }
27 
28         private void StackPanel_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
29         {
30             StackPanel element = (StackPanel)e.OriginalSource;
31             e.ManipulationContainer = this.myGrid;
32             e.Mode = ManipulationModes.All;
33         }
34 
35         private void StackPanel_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
36         {
37             FrameworkElement element = (FrameworkElement)e.Source;
38             Matrix matrix = ((MatrixTransform)element.RenderTransform).Matrix;
39             ManipulationDelta deltaManipulation = e.DeltaManipulation;
40             Point center = new Point(element.ActualWidth / 2, element.ActualHeight / 2);
41             center = matrix.Transform(center);
42             matrix.ScaleAt(deltaManipulation.Scale.X, deltaManipulation.Scale.Y, center.X, center.Y);
43             matrix.RotateAt(e.DeltaManipulation.Rotation, center.X, center.Y);
44             matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
45             ((MatrixTransform)element.RenderTransform).Matrix = matrix;
46         }
47 
48         private void StackPanel_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
49         {
50 
51         }
52     }
53 }

第二階段:

<這里我想把它推上首頁了,因為很多地方肯定沒有做好,希望各位提提寶貴意見,還有一些問題想請教大家.還有很多地方注釋沒有完善

,因為我是現寫的,請大家多多包容>

  上一章,我們完成了觸控條件下的操作,但是現在有一個問題:鼠標腫么辦?

  解決方案:利用MouseLeftButtonDown,MouseMove,MouseLeftButtonUp寫.

  還有需求中的要點擊怎么辦?

  解決方案:這個我是要腫么辦呢?決定用Touch事件做了.但是感覺又跟Manipulation重復了.詳情請看代碼.Touch事件和Manipulation事件重復了,沒有注釋掉,可以注釋掉Manipulation事件,各位親自理.

  遇到問題:當鼠標和觸摸兩個事件一起發生時,會發生一起奇怪的現象,我做了處理,但是不能夠解決,各位大大有什么看法?  

 1 <Window x:Class="LearnWpf.ManipulationDemo"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="ManipulationDemo" WindowState="Maximized" Height="300" Width="300" MouseLeftButtonDown="Window_MouseLeftButtonDown" MouseMove="Window_MouseMove" MouseLeftButtonUp="Window_MouseLeftButtonUp">
 5     <Grid x:Name="myGrid">
 6         <StackPanel x:Name="myStackPanel"
 7                     Background="Red" Height="200" Width="200"
 8                     ManipulationStarting="StackPanel_ManipulationStarting" ManipulationDelta="StackPanel_ManipulationDelta" ManipulationCompleted="StackPanel_ManipulationCompleted"
 9                     TouchDown="myStackPanel_TouchDown" TouchMove="myStackPanel_TouchMove" TouchUp="myStackPanel_TouchUp"/>
10     </Grid>
11 </Window>
  1 CSharp Code 
  2  using System;
  3  using System.Collections.Generic;
  4  using System.Linq;
  5  using System.Text;
  6  using System.Windows;
  7  using System.Windows.Controls;
  8  using System.Windows.Data;
  9  using System.Windows.Documents;
 10  using System.Windows.Input;
 11  using System.Windows.Media;
 12  using System.Windows.Media.Imaging;
 13  using System.Windows.Shapes;
 14  
 15  namespace LearnWpf
 16  {
 17      /// <summary>
 18      /// ManipulationDemo.xaml 的交互邏輯
 19      /// </summary>
 20      public partial class ManipulationDemo : Window
 21      {
 22          FrameworkElement frameworkElement; //想要操縱的元素
 23          bool isFrameworkElementSelect; //想要用鼠標移動的元素是否被選中
 24          bool isMouse = false; //鼠標操作中
 25          bool isTouch = false; //觸摸操作中
 26          public ManipulationDemo()
 27          {
 28              InitializeComponent();
 29              frameworkElement = this.myStackPanel;
 30              myStackPanel.RenderTransform = new MatrixTransform();
 31              myStackPanel.IsManipulationEnabled = true;
 32          }
 33  
 34          private void StackPanel_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
 35          {
 36              frameworkElement = (FrameworkElement)e.OriginalSource;
 37              e.ManipulationContainer = this.myGrid;
 38              e.Mode = ManipulationModes.All;
 39              frameworkElement.Opacity = 0.5;
 40          }
 41  
 42          private void StackPanel_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
 43          {
 44              FrameworkElement element = (FrameworkElement)e.Source;
 45              Matrix matrix = ((MatrixTransform)element.RenderTransform).Matrix;
 46              ManipulationDelta deltaManipulation = e.DeltaManipulation;
 47              Point center = new Point(element.ActualWidth / 2, element.ActualHeight / 2);
 48              center = matrix.Transform(center);
 49              matrix.ScaleAt(deltaManipulation.Scale.X, deltaManipulation.Scale.Y, center.X, center.Y);
 50              matrix.RotateAt(e.DeltaManipulation.Rotation, center.X, center.Y);
 51              //matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
 52              ((MatrixTransform)element.RenderTransform).Matrix = matrix;
 53          }
 54  
 55          private void StackPanel_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
 56          {
 57              frameworkElement.Opacity = 1;
 58          }
 59  
 60          #region 坐標的相關變量定義
 61          double dx; //x軸方向的每次移動的距離
 62          double dy; //y軸方向每次移動的距離
 63  
 64          double tdx; //x軸方向的每次移動的總距離
 65          double tdy; //y軸方向的每次移動的總距離
 66  
 67          double opx; //舊的x軸的值
 68          double opy; //舊的y軸的值
 69  
 70          double npx; //新的x軸的值
 71          double npy; //新的y軸的值
 72          #endregion
 73  
 74          #region Touch事件
 75          private void myStackPanel_TouchDown(object sender, TouchEventArgs e)
 76          {
 77              if (isMouse) return;
 78              isTouch = true;
 79  
 80              tdx = 0;
 81              tdy = 0;
 82  
 83              Point p = e.GetTouchPoint(this).Position;
 84              opx = p.X;
 85              opy = p.Y;
 86          }
 87          private void myStackPanel_TouchMove(object sender, TouchEventArgs e)
 88          {
 89              if (isMouse) return;
 90  
 91              Point p = e.GetTouchPoint(this).Position; 
 92              npx = p.X;
 93              npy = p.Y;
 94              dx = npx - opx;
 95              dy = npy - opy;
 96              opx = npx;
 97              opy = npy;
 98  
 99              tdx += Math.Abs(dx);
100              tdy += Math.Abs(dy);
101              Move(dx, dy);
102          }
103          private void myStackPanel_TouchUp(object sender, TouchEventArgs e)
104          {
105              if (isMouse) return;
106  
107              if (tdx < 5 || tdy < 5)
108              {
109                  Click();
110              }
111  
112              isTouch = false;
113          }
114          #endregion
115  
116          /// <summary>
117          /// 移動frameElement方法
118          /// </summary>
119          /// <param name="dx"></param>
120          /// <param name="dy"></param>
121          private void Move(double dx,double dy) 
122          {
123              Matrix matrix = ((MatrixTransform)frameworkElement.RenderTransform).Matrix;
124              matrix.Translate(dx, dy);
125              this.frameworkElement.RenderTransform = new MatrixTransform(matrix);
126          }
127  
128          /// <summary>
129          /// Click觸發的方法
130          /// </summary>
131          private void Click()
132          {
133              MessageBox.Show("U hurt me");
134          }
135  
136          private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
137          {
138              if (isTouch) return;
139              isMouse = true;
140  
141              tdx = 0;
142              tdy = 0;
143  
144              frameworkElement.Opacity = 0.5;
145              frameworkElement = (FrameworkElement)e.OriginalSource;
146              isFrameworkElementSelect = true;
147              Point p = e.GetPosition(this);
148              opx = p.X;
149              opy = p.Y;
150             
151          }
152  
153          private void Window_MouseMove(object sender, MouseEventArgs e)
154          {
155              if (isTouch) return;
156              
157              if (isFrameworkElementSelect)
158              {
159                  Point p = e.GetPosition(this);
160                  npx = p.X;
161                  npy = p.Y;
162                  dx = npx - opx;
163                  dy = npy - opy;
164                  opx = npx;
165                  opy = npy;
166  
167                  tdx += Math.Abs(dx);
168                  tdy += Math.Abs(dy);
169                  Move(dx, dy);
170              }
171          }
172  
173          private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
174          {
175              if (isTouch) return;
176  
177              frameworkElement.Opacity = 1;
178              isFrameworkElementSelect = false;
179              if (tdx < 5 || tdy < 5)
180              {
181                  Click();
182              }
183  
184              isMouse = false;
185          }
186      }
187  }

11/15/2012 初次整理

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM