原文:WPF之Manipulation

需求:现,在窗口下有一个StackPanel控件.

  1.可以拖动.

  2.可以展开及收缩(不仅仅可以拖动还可以点击)

  3.窗口向坐标轴一样分四个象限,在不同的区域停靠在不同的地方(四个角).

第一阶段:

  我遇到的问题:

  1.起初完成的时候发现StackPanel拖动的时候一直发疯一样的抖,

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

  2.为啥写了之后触控点不动?

   解决发发:查看构造函数中myStackPanel.RenderTransform = new MatrixTransform(),但是这样做会给后面留下新的问题,花了我一天时间找出这处.后面详述.

 Xaml's code:

 <Window x:Class="LearnWpf.ManipulationDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ManipulationDemo" Height="300" Width="300">
<Grid x:Name="myGrid">
<StackPanel x:Name="myStackPanel"
Background="Red" Height="50" Width="50"
ManipulationStarting="StackPanel_ManipulationStarting"
ManipulationDelta="StackPanel_ManipulationDelta"
ManipulationCompleted="StackPanel_ManipulationCompleted"
/>
</Grid>
</Window>
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes; namespace LearnWpf
{
/// <summary>
/// ManipulationDemo.xaml 的交互逻辑
/// </summary>
public partial class ManipulationDemo : Window
{
public ManipulationDemo()
{
InitializeComponent();
myStackPanel.RenderTransform = new MatrixTransform();
myStackPanel.IsManipulationEnabled = true;
} private void StackPanel_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
{
StackPanel element = (StackPanel)e.OriginalSource;
e.ManipulationContainer = this.myGrid;
e.Mode = ManipulationModes.All;
} private void StackPanel_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
FrameworkElement element = (FrameworkElement)e.Source;
Matrix matrix = ((MatrixTransform)element.RenderTransform).Matrix;
ManipulationDelta deltaManipulation = e.DeltaManipulation;
Point center = new Point(element.ActualWidth / , element.ActualHeight / );
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);
((MatrixTransform)element.RenderTransform).Matrix = matrix;
} private void StackPanel_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{ }
}
}

第二阶段:

<这里我想把它推上首页了,因为很多地方肯定没有做好,希望各位提提宝贵意见,还有一些问题想请教大家.还有很多地方注释没有完善

,因为我是现写的,请大家多多包容>

  上一章,我们完成了触控条件下的操作,但是现在有一个问题:鼠标肿么办?

  解决方案:利用MouseLeftButtonDown,MouseMove,MouseLeftButtonUp写.

  还有需求中的要点击怎么办?

  解决方案:这个我是要肿么办呢?决定用Touch事件做了.但是感觉又跟Manipulation重复了.详情请看代码.Touch事件和Manipulation事件重复了,没有注释掉,可以注释掉Manipulation事件,各位亲自理.

  遇到问题:当鼠标和触摸两个事件一起发生时,会发生一起奇怪的现象,我做了处理,但是不能够解决,各位大大有什么看法?  

 <Window x:Class="LearnWpf.ManipulationDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ManipulationDemo" WindowState="Maximized" Height="300" Width="300" MouseLeftButtonDown="Window_MouseLeftButtonDown" MouseMove="Window_MouseMove" MouseLeftButtonUp="Window_MouseLeftButtonUp">
<Grid x:Name="myGrid">
<StackPanel x:Name="myStackPanel"
Background="Red" Height="200" Width="200"
ManipulationStarting="StackPanel_ManipulationStarting" ManipulationDelta="StackPanel_ManipulationDelta" ManipulationCompleted="StackPanel_ManipulationCompleted"
TouchDown="myStackPanel_TouchDown" TouchMove="myStackPanel_TouchMove" TouchUp="myStackPanel_TouchUp"/>
</Grid>
</Window>
 CSharp Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes; namespace LearnWpf
{
/// <summary>
/// ManipulationDemo.xaml 的交互逻辑
/// </summary>
public partial class ManipulationDemo : Window
{
FrameworkElement frameworkElement; //想要操纵的元素
bool isFrameworkElementSelect; //想要用鼠标移动的元素是否被选中
bool isMouse = false; //鼠标操作中
bool isTouch = false; //触摸操作中
public ManipulationDemo()
{
InitializeComponent();
frameworkElement = this.myStackPanel;
myStackPanel.RenderTransform = new MatrixTransform();
myStackPanel.IsManipulationEnabled = true;
} private void StackPanel_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
{
frameworkElement = (FrameworkElement)e.OriginalSource;
e.ManipulationContainer = this.myGrid;
e.Mode = ManipulationModes.All;
frameworkElement.Opacity = 0.5;
} private void StackPanel_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
FrameworkElement element = (FrameworkElement)e.Source;
Matrix matrix = ((MatrixTransform)element.RenderTransform).Matrix;
ManipulationDelta deltaManipulation = e.DeltaManipulation;
Point center = new Point(element.ActualWidth / , element.ActualHeight / );
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);
((MatrixTransform)element.RenderTransform).Matrix = matrix;
} private void StackPanel_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
frameworkElement.Opacity = ;
} #region 坐标的相关变量定义
double dx; //x轴方向的每次移动的距离
double dy; //y轴方向每次移动的距离 double tdx; //x轴方向的每次移动的总距离
double tdy; //y轴方向的每次移动的总距离 double opx; //旧的x轴的值
double opy; //旧的y轴的值 double npx; //新的x轴的值
double npy; //新的y轴的值
#endregion #region Touch事件
private void myStackPanel_TouchDown(object sender, TouchEventArgs e)
{
if (isMouse) return;
isTouch = true; tdx = ;
tdy = ; Point p = e.GetTouchPoint(this).Position;
opx = p.X;
opy = p.Y;
}
private void myStackPanel_TouchMove(object sender, TouchEventArgs e)
{
if (isMouse) return; Point p = e.GetTouchPoint(this).Position;
npx = p.X;
npy = p.Y;
dx = npx - opx;
dy = npy - opy;
opx = npx;
opy = npy; tdx += Math.Abs(dx);
tdy += Math.Abs(dy);
Move(dx, dy);
}
private void myStackPanel_TouchUp(object sender, TouchEventArgs e)
{
if (isMouse) return; if (tdx < || tdy < )
{
Click();
} isTouch = false;
}
#endregion /// <summary>
/// 移动frameElement方法
/// </summary>
/// <param name="dx"></param>
/// <param name="dy"></param>
private void Move(double dx,double dy)
{
Matrix matrix = ((MatrixTransform)frameworkElement.RenderTransform).Matrix;
matrix.Translate(dx, dy);
this.frameworkElement.RenderTransform = new MatrixTransform(matrix);
} /// <summary>
/// Click触发的方法
/// </summary>
private void Click()
{
MessageBox.Show("U hurt me");
} private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (isTouch) return;
isMouse = true; tdx = ;
tdy = ; frameworkElement.Opacity = 0.5;
frameworkElement = (FrameworkElement)e.OriginalSource;
isFrameworkElementSelect = true;
Point p = e.GetPosition(this);
opx = p.X;
opy = p.Y; } private void Window_MouseMove(object sender, MouseEventArgs e)
{
if (isTouch) return; if (isFrameworkElementSelect)
{
Point p = e.GetPosition(this);
npx = p.X;
npy = p.Y;
dx = npx - opx;
dy = npy - opy;
opx = npx;
opy = npy; tdx += Math.Abs(dx);
tdy += Math.Abs(dy);
Move(dx, dy);
}
} private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (isTouch) return; frameworkElement.Opacity = ;
isFrameworkElementSelect = false;
if (tdx < || tdy < )
{
Click();
} isMouse = false;
}
}
}

11/15/2012 初次整理

WPF之Manipulation的更多相关文章

  1. WPF Multi-Touch 开发:高级触屏操作(Manipulation)

    原文 WPF Multi-Touch 开发:高级触屏操作(Manipulation) 在上一篇中我们对基础触控操作有了初步了解,本篇将继续介绍触碰控制的高级操作(Manipulation),在高级操作 ...

  2. #747 –在WPF程序的触摸操作中使用惯性移动 (Implementing Inertia during Touch Manipulation)

    原文:#747 –在WPF程序的触摸操作中使用惯性移动 (Implementing Inertia during Touch Manipulation) 原文地址:https://wpf.2000th ...

  3. Data Binding in WPF

    http://msdn.microsoft.com/en-us/magazine/cc163299.aspx#S1   Data Binding in WPF John Papa Code downl ...

  4. WPF 路由事件

    最近想封装一个关于手势的控件,但是由其他的控件覆盖之后发现不能触发,据说是有一些事件在定义的时候就处理过e.Handle了. 定义的时候就处理了,就是为了控件能够正常的工作,别如Button.Mous ...

  5. WPF中的多点触摸事件

    UIElement在WPF4下添加了很多支持多点触摸的事件,通过它们可以在硬件支持的情况下处理多点触摸,以下通过代码来说明通过处理这些事件,我们可以做些什么: 一.触摸相关的多种事件,跟鼠标事件是对应 ...

  6. MSDN 杂志:UI 前沿技术 - WPF 中的多点触控操作事件

    原文  MSDN 杂志:UI 前沿技术 - WPF 中的多点触控操作事件 UI 前沿技术 WPF 中的多点触控操作事件 Charles Petzold 下载代码示例 就在过去几年,多点触控还只是科幻电 ...

  7. WPF Multi-Touch 开发:高效开发模式

    原文 WPF Multi-Touch 开发:高效开发模式 在前几篇文章中已经介绍了触屏操作的多种模式,并对其开发方式也有了进一步了解.细心的朋友应该会发现在上一篇文章中,如果拖动图片过快它会因惯性效果 ...

  8. WPF Multi-Touch 开发:惯性效果(Inertia)

    原文 WPF Multi-Touch 开发:惯性效果(Inertia) 从上一篇实例可以发现在图片移动过程中如果将手指移开屏幕则图片会立刻停止,根据这种情况WPF 提供另外一种惯性效果(Inertia ...

  9. WPF学习(6)路由事件

    做过.net开发的朋友对于事件应该都不陌生.追溯历史,事件(Event)首先应用在Com和VB上,它是对在MFC中使用的烦琐的消息机制的一个封装,然后.net又继承了这种事件驱动机制,这种事件也叫.n ...

随机推荐

  1. 单元测试(四)-隔离框架NSubstitute

    之前学习了单元测试的基础知识,以及桩对象和模拟对象的不同作用.但在实际应用中,往往不会直接手写桩对象或者模拟对象,而是使用隔离框架动态的创建这些对象,这可以让测试变得更简便.快捷,还可以更好地应对复杂 ...

  2. AOP编程 - 淘宝京东网络处理

    现象描述 当我们打开京东 app 进入首页,如果当前是没有网络的状态,里面的按钮点击是没有反应的.只有当我们打开网络的情况下,点击按钮才能跳转页面,按照我们一般人写代码的逻辑应该是这个样子: /** ...

  3. React Native 二维码扫描组件

    学rn得朋友们,你们知道rn开源项目吗?来吧看这里:http://www.marno.cn/(rn开源项目) React Native学习之路(9) - 注册登录验证的实现 + (用Fetch实现po ...

  4. Android 开源库和项目 3

    Android 开源库和项目 Android 开源库和项目 2 1.Matisse Android 图片选择器 -- 知乎开源 github 地址:https://github.com/zhihu/M ...

  5. innodb 表锁和行锁

    表锁  表锁相关结构: table->locks:数据字典table保存这个表上的所有表锁信息 trx->lock.table_locks:每个事务trx保存该事务所加的所有表锁信息 tr ...

  6. Oracle EBS GL总账凭证取值

    SELECT gh.je_header_id, gh.period_name, gh.default_effective_date, gh.je_source, gs.user_je_source_n ...

  7. 总结获取原生JS(javascript)的父节点、子节点、兄弟节点

    关于原生JS获取节点,一直是个头疼的问题,而且调用方法的名字又贼长了,所以我选择用JQ,好像跑题了-- 话不多说看代码 获取父节点 及 父节点下所有子节点(兄弟节点) <ul> <l ...

  8. Chrome 无法加载Shockwave Flash

    遇到的问题 Chrome经常出现上图的提示,把Adobe Flash重装了N多次也是无法解决此问题,经多次尝试终于解决此问题. 解决方法 1.在Chrome地址栏输入:chrome://plugins ...

  9. sysbench压力测试工具安装及使用

    使用sysbench指定连接的时候不需要写上mysql-socket参数 如果自己使用sysbench来测试mysql性能的话,建议使用源码编译比较好,版本为0.4版本. 步骤是: .yum inst ...

  10. MySQL日常运维操作---持续更新

    1.查看当前连接数: 这些参数都是什么意思呢? Threads_cached ##mysql管理的线程池中还有多少可以被复用的资源 Threads_connected ##打开的连接数 Threads ...