天天看點

WPF4多點觸摸事件

UIElement在WPF4下添加了很多支援多點觸摸的事件,通過它們可以在硬體支援的情況下處理多點觸摸,以下通過代碼來說明通過處理這些事件,我們可以做些什麼:

一.觸摸相關的多種事件,跟滑鼠事件是對應的,通過這些事件可以擷取到多個觸摸的滑鼠點,并進行相應的處理

public static readonly RoutedEvent TouchDownEvent;

public static readonly RoutedEvent TouchEnterEvent;

public static readonly RoutedEvent TouchLeaveEvent;

public static readonly RoutedEvent TouchMoveEvent;

public static readonly RoutedEvent TouchUpEvent;

以上每個事件都包含一個TouchEventArgs參數,通過該參數可以擷取到一個TouchDevice資訊,對應于每一次觸摸,還可以通過 GetTouchPoint得到一個TouchPoint,TouchPoint包含目前觸摸的動作,觸摸的位置等資訊,通過擷取到的 TouchDevice,我們可以處理每一次觸摸(通過判斷TouchDevice的ID号來分辨不同的觸摸),并通過TouchPoint擷取觸摸的坐 标點,進而實作一些多點的邏輯,例如多點的書寫(通過擷取的TouchPoint來生成PathFigure,形成PathGeometry,最終填充成 Path來繪制)

二.Manipulation事件,通過這些事件可以實作UIElement的一些多點手勢(移動,旋轉,縮放)

public static readonly RoutedEvent ManipulationCompletedEven;

public static readonly RoutedEvent ManipulationDeltaEvent;

public static readonly RoutedEvent ManipulationInertiaStartingEvent;

public static readonly RoutedEvent ManipulationStartedEvent;

1.要處理Manipulation事件,首先必須設定UIElement的IsManipulationEnabled為true

2.ManipulationInertiaStartingEvent事件包含一個ManipulationStartingEventArgs參數,通過該參數可以設定:

UIElement的ManipulationContainer —— 設定該UIElement的容器

Mode —— 處理的事件類型,包含以下枚舉

None:不處理

TranslateX:處理水準移動

TranslateY:處理垂直移動

Translate:處理移動

Rotate:處理旋轉

Scale:處理縮放

All:處理所有事件

3.要實作控件的移動,縮放,旋轉,可以在控件的ManipulationDeltaEvent事件中使用以下代碼:

 private void image_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)

        {

            var element = e.Source as FrameworkElement;

            if (element != null)

            {

                try

                {

                    ManipulationDelta deltaManipulation = e.DeltaManipulation;

                    Matrix matrix = element.RenderTransform.Value;

                    Point center = new Point(element.ActualWidth / 2, element.ActualHeight / 2); 

                    center = matrix.Transform(center);  //設定中心點

                    //處理縮放

                    matrix.ScaleAt(deltaManipulation.Scale.X, deltaManipulation.Scale.Y, center.X, center.Y);

                    // 處理旋轉

                    matrix.RotateAt(e.DeltaManipulation.Rotation, center.X, center.Y);

                    //處理移動

                    matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);

                    element.RenderTransform = new MatrixTransform(matrix);

                    e.Handled = true;

                }

                catch (Exception ei)

                    MessageBox.Show(ei.ToString());

            }

        }

4.此外可以在ManipulationInertiaStarting事件中設定慣性效果

private void image_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)

            // 移動慣性

            e.TranslationBehavior = new InertiaTranslationBehavior()

                InitialVelocity = e.InitialVelocities.LinearVelocity,

                DesiredDeceleration = 1 / (1000.0 * 1000.0)   // 機關:一個WPF機關 / ms

            };

            // 縮放慣性

            e.ExpansionBehavior = new InertiaExpansionBehavior()

                InitialVelocity = e.InitialVelocities.ExpansionVelocity,

                DesiredDeceleration = 1 / 1000.0 * 1000.0   // 機關:一個WPF機關 / ms

            // 旋轉慣性

            e.RotationBehavior = new InertiaRotationBehavior()

                InitialVelocity = e.InitialVelocities.AngularVelocity,

                DesiredDeceleration = 720 / (1000.0 * 1000.0)  //機關:一個角度 / ms

            e.Handled = true;

5.在設定了慣性事件後,如果不處理判斷控件容器的邊界,那很容易一個移動就會把控件移到螢幕外部,是以此時可以在ManipulationDeltaEvent事件中加入以下代碼:

   if (e.IsInertial)

   {

           Rect containingRect = new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize);

           Rect shapeBounds = element.RenderTransform.TransformBounds(new Rect(element.RenderSize));

           if (e.IsInertial && !containingRect.Contains(shapeBounds))

           {

                 e.ReportBoundaryFeedback(e.DeltaManipulation);    

                 e.Complete();

    }    

三.總結

WPF4直接加入了Manipulation事件來支援對UIElement手勢的移動,旋轉和縮放,也加入了各種觸摸事件來處理多個點的觸摸,通過這些事件可以擷取到多點觸摸的坐标,進而實作各種多點邏輯