Asp.Net教程,WinForm教程,Asp.Net MVC,vs2008教程,vs2010教程,Silverlight技术,源码下载,Asp.Net视频教程
全站热门标签
vs2010 Silverlight 存储过程 水晶报表 ADO.NET JavaScript LINQ AjaxPro DataGridView 面向对象 Extjs GridView XML DevExpress HTML教程 Oracle jQuery 分页 GDI+ Visual C++2010 MySQL Office2010 WPF MVC Dojo WCF4.0 VB.NET Sql2005 textbox cookie WCF WinForm Discuz!NT SQL经典语句 T-SQL checkbox ASPxGridView F# asp.net SQL VS2008新特性 DropDownList Access TreeView Ajax VS2008 页面执行时间 Flex 字符串 回调 VB2005 DataSet C#时间 ASP.NET性能优化 用户在线检测 动画
当前位置: 主页 > vs2010教程 >

基于Visual C#2010开发Windows7应用 多点触摸图片处理应用程序(1)-同时处理多张图片(3)

时间:2010-07-28 12:30来源:blog.csdn.net/yincheng01 作者:admin 点击:

 

5.   更改以下事件处理程序的签名和代码:
注意:此事件处理程序的签名已经更改。我们使用StylusEventArgs 代替与鼠标相关的事件参数。
(代码片段 – MultiTouch – StylusEventHandlers CSharp)

 

public void ProcessDown(object sender, StylusEventArgs args)  
 
{  
 
    _prevLocation = args.GetPosition(_canvas);  
 
    _picture = FindPicture(_prevLocation);  
 
    BringPictureToFront(_picture);  
 
}  
 
public void ProcessMove(object sender, StylusEventArgs args)  
 
{  
 
    if (_picture == null)  
 
        return;  
 
    Point newLocation = args.GetPosition(_canvas);  
 
    _picture.X += newLocation.X - _prevLocation.X;  
 
    _picture.Y += newLocation.Y - _prevLocation.Y;  
 
    _prevLocation = newLocation;  
 
}  
 
 
public void ProcessUp(object sender, StylusEventArgs args)  
 
{  
 
    _picture = null;  
 

 

6. 注册触笔事件。

public MainWindow()  
 
{  
 
...  
 
    //注册(触摸)事件  
 
    StylusDown += ProcessDown;  
 
    StylusUp += ProcessUp;  
 
    StylusMove += ProcessMove;  
 

 

7.  编译并运行。使用手指代替鼠标! 
注意: 如果尝试使用多个手指会发生什么情况?为什么? 
 同时处理多张图片  
在本任务中,我们将添加多点触摸支持。触摸屏幕的每个手指都会获得一个唯一的触摸 ID。只要这根手指继续触摸屏幕,系统就会将相同的触摸 ID 与该手指关联。当手指离开屏幕表面时,该触摸 ID 将被系统释放并可被硬件再次使用。在我们的示例中,当一根手指触摸图片时,应该将该手指的唯一触摸 ID 与该图片关联,直到该手指离开屏幕。如果两个或更多手指同时触摸屏幕,那么每个手指都可以操作相关的图片。
当使用 Stylus 事件作为触摸事件时,可以从 Stylus 事件参数中提取出触摸 ID:args.StylusDevice.Id 
WPF 将使用相关的 StylusDevice.Id(触摸 ID)不断为每个触摸屏幕的手指触发事件。
1.  我们需要同时跟踪多张图片。对于每张图片,触摸 ID、上一个位置与图片用户控件之间必须保持关联。我们将首先添加一个新的 PictureTracker 类:
注意:PictureTracker 类也在 %TrainingKitInstallDir%\MultiTouch\Assets\PictureHandling下以实验资源的形式提供,请选择您想要使用的语言(C#)。

 

class PictureTracker  
 
{  
 
       private Point _prevLocation;  
 
       public Picture Picture { get; set; }  
 
       public void ProcessDown(Point location)  
 
       {  
 
           _prevLocation = location;  
 
       }  
 
       public void ProcessMove(Point location)  
 
       {  
 
           Picture.X += location.X - _prevLocation.X;  
 
           Picture.Y += location.Y - _prevLocation.Y;  
 
           _prevLocation = location;  
 
       }  
 
       public void ProcessUp(Point location)  
 
       {  
 
           //什么都不做,可能有另一个触摸ID仍下跌  
 
       }  
 

 

2.  现在我们需要一个词典,以将活动的触摸 ID 映射到相应的 PictureTracker 实例。我们将创建一个 PictureTrackerManager 类来包含该词典并处理各种触摸事件。无论何时触发了触摸事件,PictureTrackerManager 都将尝试找到关联的 PictureTracker 实例并要求它处理该触摸事件。换言之,PictureTrackerManager 将获得触摸事件。它寻找作为实际事件目标的 PictureTracker 实例并将触摸事件分派给它。现在的问题是如何找到正确的 PictureTracker 实例。我们需要考虑一些不同的场景:

a.  发生 ProcessDown 事件时,有 3 种选择:

i.              手指触摸一个空位置。不会发生任何事件。

ii.             手指触摸新图片。必须创建一个新 PictureTracker 实例,必须在触摸 ID 映射中创建一个新条目。

iii.            第 2 个(或更多)手指触摸已经被跟踪的图片。我们必须将新的触摸 ID 与相同的 PictureTracker 实例相关联。

b.            发生 ProcessMove 事件时,有 2 种选择:

i.              手指的触摸 ID 未与一个 PictureTracker 相关联。不应该发生任何事件。

ii.             手指的触摸 ID 与一个 PictureTracker 关联。我们需要将事件转发给它。

c.             发生 ProcessUp 事件时,有 2 种选择:

i.              删除了一个手指触摸 ID,但是至少还存在一个相关的触摸 ID。我们需要从映射中删除此条目。

ii.             删除了最后一个相关的触摸 ID。我们需要从映射中删除该条目。图片跟踪器不再使用并且会被当作垃圾收集走。

3.            通过分析这些情形,我们可以定义 PictureTrackerManager 的设计条件:

a.            它必须拥有一个映射:触摸 ID PictureTracker

private readonly Dictionary<int, PictureTracker> _pictureTrackerMap 

4.   添加以下 PictureTrackerManager 类:

注意:PictureTrackerManager 类也以实验资产的形式在 %TrainingKitInstallDir%\MultiTouch\Assets\PictureHandling 下提供,

class PictureTrackerManager  
 
{  
 
    //图片之间的接触和ID跟踪  
    private readonly Dictionary<int, PictureTracker> _pictureTrackerMap = new Dictionary<int, PictureTracker>();  
 
    private readonly Canvas _canvas;  
 
    public PictureTrackerManager(Canvas canvas)  
 
    {  
 
        _canvas = canvas;  
 
    }  
 
    public void ProcessDown(object sender, StylusEventArgs args)  
 
    {  
 
        Point location = args.GetPosition(_canvas);  
 
        PictureTracker pictureTracker = GetPictureTracker(args.StylusDevice.Id, location);  
 
        if (pictureTracker == null)  
 
            return;  
 
        pictureTracker.ProcessDown(location);  
 
    }  
 
    public void ProcessUp(object sender, StylusEventArgs args)  
 
    {  
 
        Point location = args.GetPosition(_canvas);  
 
        PictureTracker pictureTracker = GetPictureTracker(args.StylusDevice.Id);  
 
        if (pictureTracker == null)  
 
            return;  
 
        pictureTracker.ProcessUp(location);  
 
        _pictureTrackerMap.Remove(args.StylusDevice.Id);  
 
    }  
 
    public void ProcessMove(object sender, StylusEventArgs args)  
 
    {  
 
        PictureTracker pictureTracker = GetPictureTracker(args.StylusDevice.Id);  
 
        if (pictureTracker == null)  
 
            return;  
 
        Point location = args.GetPosition(_canvas);  
 
        pictureTracker.ProcessMove(location);  
 
    }  
 
    private PictureTracker GetPictureTracker(int touchId)  
 
    {  
 
        PictureTracker pictureTracker = null;  
 
        _pictureTrackerMap.TryGetValue(touchId, out pictureTracker);  
 
        return pictureTracker;  
 
    }  
 
    private PictureTracker GetPictureTracker(int touchId, Point location)  
 
    {  
 
        PictureTracker pictureTracker;  
 
        //我们已经根据笔触ID追踪到了图片  
        if (_pictureTrackerMap.TryGetValue(touchId, out pictureTracker))  
 
            return pictureTracker;  
 
        //获取图片下的触摸位置  
        Picture picture = FindPicture(location);  
 
        if (picture == null)  
 
            return null;  
 
        //我们根据其他ID来追踪图片  
 
        pictureTracker = (from KeyValuePair<int, PictureTracker> entry in _pictureTrackerMap  
 
                           where entry.Value.Picture == picture  
 
                           select entry.Value).FirstOrDefault();  
 
        //第一次  
 
        if (pictureTracker == null)  
 
        {  
 
            //创建  
 
            pictureTracker = new PictureTracker();  
 
            pictureTracker.Picture = picture;  
 
            BringPictureToFront(picture);  
 
        }  
 
        //记得接触ID和图片之间的相关性实证分析  
        _pictureTrackerMap[touchId] = pictureTracker;  
 
         return pictureTracker;  
 
    }  
 
    /// <summary>  
 
    /// 在触摸位置中找到图片  
 
    /// </summary>  
 
    /// <param name="pointF">触摸位置</param>  
 
    /// <returns>空的图片或照片,如果没有在触摸位置存在</returns>  
 
    private Picture FindPicture(Point location)  
 
    {  
 
        HitTestResult result = VisualTreeHelper.HitTest(_canvas, location);  
 
        if (result == null)  
 
            return null;  
 
        Image image = result.VisualHit as Image;  
 
         if (image == null)  
 
            return null;  
 
         return image.Parent as Picture;  
 
    }  
 
    private void BringPictureToFront(Picture picture)  
 
    {  
 
        if (picture == null)  
 
            return;  
 
        var children = (from UIElement child in _canvas.Children  
 
                        where child != picture  
 
                        orderby Canvas.GetZIndex(child)  
 
                        select child).ToArray();  
 
        for (int i = 0; i < children.Length; ++i)  
 
        {  
 
            Canvas.SetZIndex(children[i], i);  
 
        }  
 
        Canvas.SetZIndex(picture, children.Length);  
 
    }  
 

5.   将以下字段声明添加到 MainWindow 类的开头:

private readonly PictureTrackerManager _pictureTrackerManager; 
private readonly PictureTrackerManager _pictureTrackerManager;

6.   修改 MainWindow 构造函数:

a.   在调用 InitializeComponent() 之后,添加管理器初始化:

_pictureTrackerManager = new PictureTrackerManager(_canvas); 
_pictureTrackerManager = new PictureTrackerManager(_canvas);

b.  更改触笔事件注册代码

//Register for stylus (touch) events  
 
StylusDown += _pictureTrackerManager.ProcessDown;  
 
StylusUp += _pictureTrackerManager.ProcessUp;  
 
StylusMove += _pictureTrackerManager.ProcessMove; 

7.   从 MainWindow 类删除 ProcessDown、ProcessMove 和 ProcessUp 事件处理程序。这里将不再需要它们,因为它们现在已包含在 PictureTrackerManager 类中。
8.    编译并运行。尝试同时抓取多张图片。尝试使用多个手指抓取一张图片。发生了什么情况?为什么?
 
<本内容未完待续...>
(责任编辑:admin)
Tags:图片处理 C#2010
责任编辑:admin
返回顶部
------分隔线----------------------------
推荐内容
骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价 骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价