您的位置:首页 > 其它

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

2012-07-10 15:14 411 查看
实现方法:

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

C# 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

namespace MetroTimeline
{
public class MetroManipulationHelper
{
/// <summary>
/// 发生碰撞时的操作方法库
/// </summary>
public static Dictionary<Predicate<string>, Action<ManipulationDeltaRoutedEventArgs>>
BoundaryFeedbackDict = new Dictionary<Predicate<string>, Action<ManipulationDeltaRoutedEventArgs>>();

/// <summary>
/// 多点触控开始后方法库
/// </summary>
public static Dictionary<Predicate<string>, Action<ManipulationStartedRoutedEventArgs>>
ManipulationStartedDict = new Dictionary<Predicate<string>, Action<ManipulationStartedRoutedEventArgs>>();

/// <summary>
/// 多点触控完成后方法库
/// </summary>
public static Dictionary<Predicate<string>, Action<ManipulationCompletedRoutedEventArgs>>
ManipulationCompletedDict = new Dictionary<Predicate<string>, Action<ManipulationCompletedRoutedEventArgs>>();

/// <summary>
/// 需要执行的方法的关键字
/// </summary>
private static string methodTag;

public static string MethodTag
{
get { return MetroManipulationHelper.methodTag; }
set { MetroManipulationHelper.methodTag = value; }
}

/// <summary>
/// 将容器变为多点操控容器
/// </summary>
/// <param name="container"></param>
/// <param name="mode"></param>
/// <param name="trans"></param>
/// <param name="scale"></param>
/// <param name="rotation"></param>
/// <param name="containerRect">容器相对父级菜单位置</param>
public static void InitManipulation(FrameworkElement container, ManipulationModes mode,
double trans, double scale, double rotation, Rect containerRect)
{

BoundaryFeedbackDict.Add(s => s.Equals("default"), e =>
{
var element = e.OriginalSource as FrameworkElement;
var con = e.Container as Panel;
var elementBounds = element.RenderTransform.TransformBounds(new Rect(e.Position, element.RenderSize));
Point fp = new Point((elementBounds.Left + elementBounds.Right) / 2, (elementBounds.Top + elementBounds.Bottom) / 2);
if (fp.X < containerRect.Left ||
fp.X > containerRect.Right ||
fp.Y < containerRect.Top ||
fp.Y > containerRect.Bottom)
{
e.Complete();
}
});
container.ManipulationStarting += ElementManipulationEventHandler(container, mode);
container.ManipulationDelta += ElementManipulationDeltaEventHandler();
container.ManipulationStarted += ElementManipulationStartedEventHandler();
container.ManipulationCompleted += ElementManipulationCompletedEventHandler();
container.ManipulationInertiaStarting += ElementManipulationInertiaStartingEventHandler(trans, scale, rotation);
foreach (var item in (container as Panel).Children)
{
if (item.ManipulationMode == ManipulationModes.All)
{
var group = new TransformGroup();
group.Children.Add(new TranslateTransform());
group.Children.Add(new ScaleTransform());
group.Children.Add(new RotateTransform());
item.RenderTransform = group;
}
}
}

#region 多点手势方法
#region 多点触控手势开始操作
public static ManipulationStartingEventHandler ElementManipulationEventHandler(FrameworkElement element, ManipulationModes mode)
{
return (sender, e) =>
{
e.Container = element;
e.Mode = mode;
};
}
#endregion

#region 多点触控手势过程中操作
public static ManipulationDeltaEventHandler ElementManipulationDeltaEventHandler()
{
return ((sender, e) =>
{
var element = e.OriginalSource as FrameworkElement;
var center = new Point(element.ActualWidth / 2, element.ActualHeight / 2);
var tt = (element.RenderTransform as TransformGroup).Children[0] as TranslateTransform;
tt.X += e.Delta.Translation.X;
tt.Y += e.Delta.Translation.Y;
var st = (element.RenderTransform as TransformGroup).Children[1] as ScaleTransform;
st.CenterX = center.X;
st.CenterY = center.Y;
st.ScaleX *= e.Delta.Scale;
st.ScaleY *= e.Delta.Scale;
var rt = (element.RenderTransform as TransformGroup).Children[2] as RotateTransform;
rt.CenterX = center.X;
rt.CenterY = center.Y;
rt.Angle += e.Delta.Rotation;
if (e.IsInertial)
if (null != BoundaryFeedbackDict)
foreach (var item in BoundaryFeedbackDict)
{
if (null != MethodTag)
if (item.Key(MethodTag)) item.Value(e);
};
});
}
#endregion

#region 多点手势开始后
private static ManipulationStartedEventHandler ElementManipulationStartedEventHandler()
{
return (sender, e) =>
{
if (null != ManipulationStartedDict)
foreach (var item in ManipulationStartedDict)
{
if (null != MethodTag)
if (item.Key(MethodTag)) item.Value(e);
};
};
}
#endregion

#region 多点手势完成
private static ManipulationCompletedEventHandler ElementManipulationCompletedEventHandler()
{
return (sender, e) =>
{
if (null != ManipulationCompletedDict)
foreach (var item in ManipulationCompletedDict)
{
if (null != MethodTag)
if (item.Key(MethodTag)) item.Value(e);
};
};
}
#endregion

#region 多点手势惯性开始
/// <summary>
///
/// </summary>
/// <param name="trans">10</param>
/// <param name="scale">0.1</param>
/// <param name="rotation">540</param>
/// <returns></returns>
private static ManipulationInertiaStartingEventHandler ElementManipulationInertiaStartingEventHandler(double trans, double scale, double rotation)
{
return (sender, e) =>
{
e.TranslationBehavior.DesiredDeceleration = trans * 96.0 / (1000.0 * 1000.0);
e.ExpansionBehavior.DesiredDeceleration = scale * 96 / 1000.0 * 1000.0;
e.RotationBehavior.DesiredDeceleration = rotation / (1000.0 * 1000.0);
};
}
#endregion
#endregion
}
}


xaml :

<Page
x:Class="MetroTimeline.MainPage"
IsTabStop="false"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MetroTimeline"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Canvas Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
Width="1080" Height="500"
x:Name="cvsContent" Tag="default">
<TextBlock Canvas.Left="573" TextWrapping="Wrap" Text="TextBlock" x:Name="tbInfo" ManipulationMode="All" Margin="219,597,171,10"/>
<Image Source="Assets/PicWallLoading.jpg" ManipulationMode="All" Height="202" Canvas.Left="75" Canvas.Top="209" Width="153"/>
<Image Source="Assets/PicWallLoading.jpg" ManipulationMode="All" Height="202" Canvas.Left="333" Canvas.Top="83" Width="153"/>
</Canvas>
</Page>


使用方式:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 
namespace MetroTimeline
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
var conRect = new Rect(Canvas.GetLeft(cvsContent), Canvas.GetTop(cvsContent),
cvsContent.Width, cvsContent.Height);
MetroManipulationHelper.InitManipulation(cvsContent, ManipulationModes.All, 5, 0.5, 360, conRect);
MetroManipulationHelper.MethodTag = cvsContent.Tag.ToString();
}

/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.  The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
}
}


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

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

最后是效果图:



demo 下载地址:http://download.csdn.net/detail/wangrenzhu2011/4420853
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐