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 ...
随机推荐
- rdlc里面的textbox怎么赋值
通过传递参数来实现 当前在rdlc页面,ctrl+alt+d,打开report data侧边栏 点击report data的Parameters文件夹,右键,添加新的参数,命名.定义类型,譬如命名为R ...
- cmd 命令总结
1.windows 系统定时关机 定时关机:shutdown -s -t 300 at 18:30 shutdown -s 取消定时:shutdown -a 注意:3 ...
- Zabbix添加Ping外网IP监控
1.先添加一个HOST,只填写IP即可,如10.1.1.1 2.选择一台客户端,新建item,如下: 3.新建trigger: 注:icmpping[<target>,<packet ...
- [cb]UIGrid+UIStretch的自适应
自适应需求 如下图所示:一个Grid下面有六个Button,它们需要在不同的分辨下拉伸适应(Horizontal)宽度,以保证填充满底部 要点分析 首先有这两个要点 1.UIGrid中的Cell Wi ...
- Git & GitHub 的安装配置
参考 教你免费搭建个人博客,Hexo&Github 安装Git 1. 注册 GitHub 注册.登录 https://github.com/ 2. 创建仓库 在 GitHub 的右上角 ...
- 【转】Java学习---集合框架那些事
[原文]https://www.toutiao.com/i6593220692525711885/ Arraylist 与 LinkedList 异同 1. 是否保证线程安全: ArrayList 和 ...
- 【史上最全】申请配置阿里云服务器,并部署IIS和开发环境,项目上线经验
最近一年在实验室做web后端开发,涉及到一些和服务器搭建及部署上线项目的相关经验,写个帖子和小伙伴们分享,一同进步! 首先谈一下,为什么越来越多中小型公司/实验室,部署项目的趋势都是在云服务器而不是普 ...
- JDK5新特性之 可变参数的方法
可变参数的方法:不知道这个方法该定义多少个参数 注意: > 参数实际上是数组 > 必须写在参数列表最后一个 package cn.itcast.day24.varparam; import ...
- Go语言学习笔记(四)结构体struct & 接口Interface & 反射reflect
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struc ...
- MySQL二进制日志文件Binlog的三种格式以及对应的主从复制中三种技术
二进制日志文件Binlog的格式主要有三种: 1.Statement:基于SQL语句级别的Binlog,每条修改数据的SQL都会保存到Binlog里面. 2.ROW:基于行级别,每一行数据的变化都会记 ...