windows8 开发教程 教你制作 多点触控Helper可将任意容器内任意对象进行多点缩放

http://blog.csdn.net/wangrenzhu2011/article/details/7732907 (转)

实现方法:


 

对Manipulation进行抽象化 使不同容器可共用多点缩放事件,

C# 代码如下:

[csharp] view plaincopyprint?
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using Windows.Foundation;  
  7. using Windows.UI.Xaml;  
  8. using Windows.UI.Xaml.Controls;  
  9. using Windows.UI.Xaml.Input;  
  10. using Windows.UI.Xaml.Media;  
  11. using Windows.UI.Xaml.Media.Animation;  
  12.   
  13. namespace MetroTimeline  
  14. {  
  15.     public class MetroManipulationHelper  
  16.     {  
  17.         /// <summary>  
  18.         /// 发生碰撞时的操作方法库  
  19.         /// </summary>  
  20.         public static Dictionary<Predicate<string>, Action<ManipulationDeltaRoutedEventArgs>>  
  21.             BoundaryFeedbackDict = new Dictionary<Predicate<string>, Action<ManipulationDeltaRoutedEventArgs>>();  
  22.   
  23.         /// <summary>  
  24.         /// 多点触控开始后方法库  
  25.         /// </summary>  
  26.         public static Dictionary<Predicate<string>, Action<ManipulationStartedRoutedEventArgs>>  
  27.             ManipulationStartedDict = new Dictionary<Predicate<string>, Action<ManipulationStartedRoutedEventArgs>>();  
  28.   
  29.         /// <summary>  
  30.         /// 多点触控完成后方法库  
  31.         /// </summary>  
  32.         public static Dictionary<Predicate<string>, Action<ManipulationCompletedRoutedEventArgs>>  
  33.             ManipulationCompletedDict = new Dictionary<Predicate<string>, Action<ManipulationCompletedRoutedEventArgs>>();  
  34.   
  35.   
  36.         /// <summary>  
  37.         /// 需要执行的方法的关键字  
  38.         /// </summary>  
  39.         private static string methodTag;  
  40.   
  41.         public static string MethodTag  
  42.         {  
  43.             get { return MetroManipulationHelper.methodTag; }  
  44.             set { MetroManipulationHelper.methodTag = value; }  
  45.         }  
  46.   
  47.   
  48.         /// <summary>  
  49.         /// 将容器变为多点操控容器  
  50.         /// </summary>  
  51.         /// <param name="container"></param>  
  52.         /// <param name="mode"></param>  
  53.         /// <param name="trans"></param>  
  54.         /// <param name="scale"></param>  
  55.         /// <param name="rotation"></param>  
  56.         /// <param name="containerRect">容器相对父级菜单位置</param>  
  57.         public static void InitManipulation(FrameworkElement container, ManipulationModes mode,  
  58.             double trans, double scale, double rotation, Rect containerRect)  
  59.         {  
  60.   
  61.             BoundaryFeedbackDict.Add(s => s.Equals("default"), e =>  
  62.             {  
  63.                 var element = e.OriginalSource as FrameworkElement;  
  64.                 var con = e.Container as Panel;  
  65.                 var elementBounds = element.RenderTransform.TransformBounds(new Rect(e.Position, element.RenderSize));  
  66.                 Point fp = new Point((elementBounds.Left + elementBounds.Right) / 2, (elementBounds.Top + elementBounds.Bottom) / 2);  
  67.                 if (fp.X < containerRect.Left ||  
  68.                     fp.X > containerRect.Right ||  
  69.                     fp.Y < containerRect.Top ||  
  70.                     fp.Y > containerRect.Bottom)  
  71.                 {  
  72.                     e.Complete();  
  73.                 }  
  74.             });  
  75.             container.ManipulationStarting += ElementManipulationEventHandler(container, mode);  
  76.             container.ManipulationDelta += ElementManipulationDeltaEventHandler();  
  77.             container.ManipulationStarted += ElementManipulationStartedEventHandler();  
  78.             container.ManipulationCompleted += ElementManipulationCompletedEventHandler();  
  79.             container.ManipulationInertiaStarting += ElementManipulationInertiaStartingEventHandler(trans, scale, rotation);  
  80.             foreach (var item in (container as Panel).Children)  
  81.             {  
  82.                 if (item.ManipulationMode == ManipulationModes.All)  
  83.                 {  
  84.                     var group = new TransformGroup();  
  85.                     group.Children.Add(new TranslateTransform());  
  86.                     group.Children.Add(new ScaleTransform());  
  87.                     group.Children.Add(new RotateTransform());  
  88.                     item.RenderTransform = group;  
  89.                 }  
  90.             }  
  91.         }  
  92.  
  93.  
  94.  
  95.         #region 多点手势方法  
  96.         #region 多点触控手势开始操作  
  97.         public static ManipulationStartingEventHandler ElementManipulationEventHandler(FrameworkElement element, ManipulationModes mode)  
  98.         {  
  99.             return (sender, e) =>  
  100.             {  
  101.                 e.Container = element;  
  102.                 e.Mode = mode;  
  103.             };  
  104.         }  
  105.         #endregion  
  106.  
  107.         #region 多点触控手势过程中操作  
  108.         public static ManipulationDeltaEventHandler ElementManipulationDeltaEventHandler()  
  109.         {  
  110.             return ((sender, e) =>  
  111.             {  
  112.                 var element = e.OriginalSource as FrameworkElement;  
  113.                 var center = new Point(element.ActualWidth / 2, element.ActualHeight / 2);  
  114.                 var tt = (element.RenderTransform as TransformGroup).Children[0] as TranslateTransform;  
  115.                 tt.X += e.Delta.Translation.X;  
  116.                 tt.Y += e.Delta.Translation.Y;  
  117.                 var st = (element.RenderTransform as TransformGroup).Children[1] as ScaleTransform;  
  118.                 st.CenterX = center.X;  
  119.                 st.CenterY = center.Y;  
  120.                 st.ScaleX *= e.Delta.Scale;  
  121.                 st.ScaleY *= e.Delta.Scale;  
  122.                 var rt = (element.RenderTransform as TransformGroup).Children[2] as RotateTransform;  
  123.                 rt.CenterX = center.X;  
  124.                 rt.CenterY = center.Y;  
  125.                 rt.Angle += e.Delta.Rotation;  
  126.                 if (e.IsInertial)  
  127.                     if (null != BoundaryFeedbackDict)  
  128.                         foreach (var item in BoundaryFeedbackDict)  
  129.                         {  
  130.                             if (null != MethodTag)  
  131.                                 if (item.Key(MethodTag)) item.Value(e);  
  132.                         };  
  133.             });  
  134.         }  
  135.         #endregion  
  136.  
  137.         #region 多点手势开始后  
  138.         private static ManipulationStartedEventHandler ElementManipulationStartedEventHandler()  
  139.         {  
  140.             return (sender, e) =>  
  141.             {  
  142.                 if (null != ManipulationStartedDict)  
  143.                     foreach (var item in ManipulationStartedDict)  
  144.                     {  
  145.                         if (null != MethodTag)  
  146.                             if (item.Key(MethodTag)) item.Value(e);  
  147.                     };  
  148.             };  
  149.         }  
  150.         #endregion  
  151.  
  152.         #region 多点手势完成  
  153.         private static ManipulationCompletedEventHandler ElementManipulationCompletedEventHandler()  
  154.         {  
  155.             return (sender, e) =>  
  156.             {  
  157.                 if (null != ManipulationCompletedDict)  
  158.                     foreach (var item in ManipulationCompletedDict)  
  159.                     {  
  160.                         if (null != MethodTag)  
  161.                             if (item.Key(MethodTag)) item.Value(e);  
  162.                     };  
  163.             };  
  164.         }  
  165.         #endregion  
  166.  
  167.         #region 多点手势惯性开始  
  168.         /// <summary>  
  169.         ///   
  170.         /// </summary>  
  171.         /// <param name="trans">10</param>  
  172.         /// <param name="scale">0.1</param>  
  173.         /// <param name="rotation">540</param>  
  174.         /// <returns></returns>  
  175.         private static ManipulationInertiaStartingEventHandler ElementManipulationInertiaStartingEventHandler(double trans, double scale, double rotation)  
  176.         {  
  177.             return (sender, e) =>  
  178.             {  
  179.                 e.TranslationBehavior.DesiredDeceleration = trans * 96.0 / (1000.0 * 1000.0);  
  180.                 e.ExpansionBehavior.DesiredDeceleration = scale * 96 / 1000.0 * 1000.0;  
  181.                 e.RotationBehavior.DesiredDeceleration = rotation / (1000.0 * 1000.0);  
  182.             };  
  183.         }  
  184.         #endregion  
  185.         #endregion  
  186.     }  
  187. }  

xaml :

  1. <Page  
  2.     x:Class="MetroTimeline.MainPage"  
  3.     IsTabStop="false"  
  4.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  5.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  6.     xmlns:local="using:MetroTimeline"  
  7.     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  8.     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  9.     mc:Ignorable="d">  
  10.   
  11.     <Canvas Background="{StaticResource ApplicationPageBackgroundThemeBrush}"  
  12.           Width="1080" Height="500"  
  13.           x:Name="cvsContent" Tag="default">  
  14.         <TextBlock Canvas.Left="573" TextWrapping="Wrap" Text="TextBlock" x:Name="tbInfo" ManipulationMode="All" Margin="219,597,171,10"/>  
  15.         <Image Source="Assets/PicWallLoading.jpg" ManipulationMode="All" Height="202" Canvas.Left="75" Canvas.Top="209" Width="153"/>  
  16.         <Image Source="Assets/PicWallLoading.jpg" ManipulationMode="All" Height="202" Canvas.Left="333" Canvas.Top="83" Width="153"/>  
  17.     </Canvas>  
  18. </Page>  


 

使用方式:

[csharp] view plaincopyprint?
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.IO;  
  4. using System.Linq;  
  5. using System.Threading.Tasks;  
  6. using Windows.Foundation;  
  7. using Windows.Foundation.Collections;  
  8. using Windows.UI.Xaml;  
  9. using Windows.UI.Xaml.Controls;  
  10. using Windows.UI.Xaml.Controls.Primitives;  
  11. using Windows.UI.Xaml.Data;  
  12. using Windows.UI.Xaml.Input;  
  13. using Windows.UI.Xaml.Media;  
  14. using Windows.UI.Xaml.Navigation;  
  15.   
  16. // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238  
  17.   
  18. namespace MetroTimeline  
  19. {  
  20.     /// <summary>  
  21.     /// An empty page that can be used on its own or navigated to within a Frame.  
  22.     /// </summary>  
  23.     public sealed partial class MainPage : Page  
  24.     {  
  25.         public MainPage()  
  26.         {  
  27.             this.InitializeComponent();           
  28.             var conRect = new Rect(Canvas.GetLeft(cvsContent), Canvas.GetTop(cvsContent),  
  29.                 cvsContent.Width, cvsContent.Height);  
  30.             MetroManipulationHelper.InitManipulation(cvsContent, ManipulationModes.All, 5, 0.5, 360, conRect);  
  31.             MetroManipulationHelper.MethodTag = cvsContent.Tag.ToString();  
  32.         }  
  33.   
  34.         /// <summary>  
  35.         /// Invoked when this page is about to be displayed in a Frame.  
  36.         /// </summary>  
  37.         /// <param name="e">Event data that describes how this page was reached.  The Parameter  
  38.         /// property is typically used to configure the page.</param>  
  39.         protected override void OnNavigatedTo(NavigationEventArgs e)  
  40.         {  
  41.         }  
  42.     }  
  43. }  


 

conRect 为当前需要操作的容器 相对他父级容器的大小以及位置,用于判断多点元素的活动范围,

如果范围是全屏的话 则无需传该参数,进行相应修改即可

最后是效果图:

demo 下载地址:http://download.csdn.net/detail/wangrenzhu2011/4420853

原文地址:https://www.cnblogs.com/CharlesGrant/p/3639228.html