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的更多相关文章
- WPF Multi-Touch 开发:高级触屏操作(Manipulation)
原文 WPF Multi-Touch 开发:高级触屏操作(Manipulation) 在上一篇中我们对基础触控操作有了初步了解,本篇将继续介绍触碰控制的高级操作(Manipulation),在高级操作 ...
- #747 –在WPF程序的触摸操作中使用惯性移动 (Implementing Inertia during Touch Manipulation)
原文:#747 –在WPF程序的触摸操作中使用惯性移动 (Implementing Inertia during Touch Manipulation) 原文地址:https://wpf.2000th ...
- Data Binding in WPF
http://msdn.microsoft.com/en-us/magazine/cc163299.aspx#S1 Data Binding in WPF John Papa Code downl ...
- WPF 路由事件
最近想封装一个关于手势的控件,但是由其他的控件覆盖之后发现不能触发,据说是有一些事件在定义的时候就处理过e.Handle了. 定义的时候就处理了,就是为了控件能够正常的工作,别如Button.Mous ...
- WPF中的多点触摸事件
UIElement在WPF4下添加了很多支持多点触摸的事件,通过它们可以在硬件支持的情况下处理多点触摸,以下通过代码来说明通过处理这些事件,我们可以做些什么: 一.触摸相关的多种事件,跟鼠标事件是对应 ...
- MSDN 杂志:UI 前沿技术 - WPF 中的多点触控操作事件
原文 MSDN 杂志:UI 前沿技术 - WPF 中的多点触控操作事件 UI 前沿技术 WPF 中的多点触控操作事件 Charles Petzold 下载代码示例 就在过去几年,多点触控还只是科幻电 ...
- WPF Multi-Touch 开发:高效开发模式
原文 WPF Multi-Touch 开发:高效开发模式 在前几篇文章中已经介绍了触屏操作的多种模式,并对其开发方式也有了进一步了解.细心的朋友应该会发现在上一篇文章中,如果拖动图片过快它会因惯性效果 ...
- WPF Multi-Touch 开发:惯性效果(Inertia)
原文 WPF Multi-Touch 开发:惯性效果(Inertia) 从上一篇实例可以发现在图片移动过程中如果将手指移开屏幕则图片会立刻停止,根据这种情况WPF 提供另外一种惯性效果(Inertia ...
- WPF学习(6)路由事件
做过.net开发的朋友对于事件应该都不陌生.追溯历史,事件(Event)首先应用在Com和VB上,它是对在MFC中使用的烦琐的消息机制的一个封装,然后.net又继承了这种事件驱动机制,这种事件也叫.n ...
随机推荐
- SQLServer 远程链接MySql数据库详解
SQLServer 远程链接MySql数据库详解 by:授客 QQ:1033553122 测试环境: Microsoft Windows XP Professional 版本2000 Service ...
- MySQL——优化ORDER BY语句
本篇文章我们将了解ORDER BY语句的优化,在此之前,你需要对索引有基本的了解,不了解的朋友们可以先看一下我之前写过的索引相关文章.现在让我们开始吧. MySQL中的两种排序方式 1.通过有序索引顺 ...
- 从ibd文件获取表空间id
xtrabackup恢复过程中出现如下错误 InnoDB: Doing recovery: scanned up to log sequence number ( %) InnoDB: Doing r ...
- unittest 常用的断言方法
1.assertEqual(self, first, second, msg=None) --判断两个参数相等:first == second 2.assertNotEqual(self, first ...
- [Hive_1] Hive 基本概念
Hive 系列01 Hive 简介 & Hive 应用场景 & Hive 与 Hadoop 的关系 & Hive 与传统数据库对比 1. Hive 简介 [ 官方介绍 ] Ap ...
- 【转】HTTP学习---图解HTTP[三次握手&&ISO模型]
[转]https://www.toutiao.com/i6592556686068679182/ 首先了解一次完整的HTTP请求到响应的过程需要的步骤: 1. 域名解析 2. 发起TCP的3次握手 3 ...
- CentOS6源码安装vim8
CentOS6源码安装vim8 vim8相比vim7多了很多功能. 不过需要源码来进行安装. 移除旧版本的vim yum remove vim 安装依赖库 sudo yum install -y ru ...
- vue+axios自己踩过的坑
axios的介绍就不用了吧,api有具体的介绍axios或者是axios中文: 主要讲的就是我自己在第一次使用axios中遇到的问题,及二次封装 先来说说二次封装,之前自己也是网上找了很多同学的封装, ...
- php linux 环境搭建
Apache源于NCSAhttpd服务器,经过多次修改,成为世界上最流行的Web服务器软件之一.Apache取自“a patchy server”的读音,意思是充满补丁的服务器,因为它是自由软件,所以 ...
- Python接口自动化--Json数据处理 5
1.Json模块简介,全名JavaScript Object Notation,轻量级的数据交换格式,常用于http请求中. Encoding basic Python object hierarch ...