原文: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. android画板笔锋实现

    前言 在安卓绘图中,path是一个很常用的类,使用它可以实现基本的画线功能,但是自己用path画出来的同一条线段大小是不会改变的.如果做书写类型的软件,当然想要实现更好的逼真的书写效果,在实际书写过程 ...

  2. Vue 2.0 v-for 响应式key, index及item.id参数对v-bind:key值造成差异研究

    Vue 2.0 v-for 响应式key, index及item.id参数对v-bind:key值造成差异研究 在github上阅览README.md以获得最佳阅读体验,点这里 v-for响应式key ...

  3. TI(德州仪器) TMS320C674x逆向分析之二

    TI官网文档: http://www.ti.com/product/tms320c6745/technicaldocuments 里面资料非常详细,可以对着里面一个个看,用的比较多的两个文档: TMS ...

  4. SQL Server FileStream (转载)

    从SQL SERVER 2008开始,SQL SERVER引入了一种新的文件组类型叫FileStream文件组,如下图所示: 那么这种文件组是用来做什么的呢? 以往我们对文件管理有两种方法: 数据库只 ...

  5. SEO-搜索引擎优化

    一.定义 SEO(Search Engine Optimization):汉译为搜索引擎优化.是一种方式:利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名.目的是:为网站提供生态式的自我营销解决方 ...

  6. 美团SQL优化工具SQLAdvisor

    介绍 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 SQL 优化,不仅可以提升程序性能,还能够降低线上故障的概率. 目前常用的 SQL 优化方式包括但不限于:业务层优化.SQL逻 ...

  7. MySQL索引设计不可忽视的知识点

    本文主要讨论MySQL索引的部分知识.将会从MySQL索引基础.索引优化实战和数据库索引背后的数据结构三部分相关内容,下面一一展开. 一.MySQL——索引基础 首先,我们将从索引基础开始介绍一下什么 ...

  8. centos7 修改中文字符集

    CentOS 7字符集的问题与6有点区别,会出现下面问题,查看是中文,vi进入就变成乱码了 生产中修改配置文件   [root@ce1d2002a999 ~]# cat /etc/locale.con ...

  9. JS中 map, filter, some, every, forEach, for in, for of 用法总结

    本文转载自:http://blog.csdn.net/gis_swb/article/details/52297343 1.map 有返回值,返回一个新的数组,每个元素为调用func的结果. let ...

  10. php可逆加密解密

    函数: function encrypt($data, $key) { $prep_code = serialize($data); $block = mcrypt_get_block_size('d ...