[WPF] PerformClick ?

简介: 原文:[WPF] PerformClick ?                                      [WPF] PerformClick ?                                                   周银辉   WPF没有提供这个方法,还真是让人觉得有些讨厌啊。
原文: [WPF] PerformClick ?

                                      [WPF] PerformClick ? 

                                                 周银辉

 

WPF没有提供这个方法,还真是让人觉得有些讨厌啊。而关于这个嘛,Google中搜一下,一大堆,但一般是利用XXXAutomationPeer。

这个原本用于支持自动化测试的,被拿来干了这事,代码如下:

         public   static   void  PerformClick( this  Button button)
        {
            var peer 
= new  ButtonAutomationPeer(button);

            var invokeProv 
=  peer.GetPattern(PatternInterface.Invoke)  as  IInvokeProvider;

            
if  (invokeProv  !=   null )
            {
                invokeProv.Invoke();
            }
        }

 
但很快地,你会发现去其依赖于具体的类:ButtonAutomationPeer, 所以WPF实现了一堆XXXAutomationPeer, 这多少让人觉得有些.... 比如“我想在任意UI元素上模拟下鼠标点击”,这种方法便不可行了,虽然有一堆Peer,再多也不是“任意”,那么用SendMessage吧,这才是王道,代码如下:

 

         public   static   void  PerformClick( this  UIElement element, Point point)
        {
            var window 
=  Window.GetWindow(element);

            
if  (window  !=   null )
            {
                var windowHwnd 
=  GetHwnd(window);

                var locOfElement 
=  element.TranslatePoint( new  Point( 0 0 ), window);
                var pointToWindow 
=   new  Point(point.X  +  locOfElement.X, point.Y  +  locOfElement.Y);

                Int32 lparam 
=  MakeLong(( int )pointToWindow.X, ( int )pointToWindow.Y);

                
//  WM_LBUTTONDOWN = 0x0201
                SendMessage(windowHwnd, WM_LBUTTONDOWN,  0 , lparam);
                
//  WM_LBUTTONUP = 0x0202;
                SendMessage(windowHwnd, WM_LBUTTONUP,  0 , lparam);
            }
        }

        
internal   static   int  MakeLong( int  lowWord,  int  highWord)
        {
            
return  (highWord  <<   16 |  (lowWord  &   0xffff );
        }

        
internal   static  IntPtr GetHwnd( this  Window window)
        {
            var winHelper 
=   new  WindowInteropHelper(window);
            
return  winHelper.Handle;
        }

 

 这个方法可以拓展到任意UI元素上,但很奇怪的是:居然不会引发Button的Click事件!从效果上看,的确点击了,因为焦点都转移上去了。那好吧,再用用下面的方法吧:反射,我比较喜欢这个方式:

         public   static   void  PerformClick( this  ButtonBase button)
        {
            var method 
=  button.GetType().GetMethod( " OnClick "
                BindingFlags.NonPublic 
|  BindingFlags.Instance);

            
if  (method  !=   null )
            {
                method.Invoke(button, 
null );
            }

            
// button.Focus();
        }

 

 

OK,总结一下:
第一种方法,依赖于具体的XXXPeer, 能力有限,不够灵活

第二种方法,较灵活,但由于SendMessage第一个参数要求传入hwnd,而WPF普通控件没有句柄,所以其依赖于窗口句柄,也就是该方法依赖窗口

第三种方法,我喜欢。有什么缺点吗?如果没有,为啥Google上的朋友们都用第一种方法?如果有,是啥?

-----------------------

[update]

最近看到一个开源项目, 专门模拟键盘和鼠标,非常棒: http://inputsimulator.codeplex.com/

源代码打包下载 : http://files.cnblogs.com/zhouyinhui/WindowsInput.zip  

使用方法嘛,比如:

 var sim  =   new  InputSimulator();
 sim.Mouse.LeftButtonDown();

 

目录
相关文章
C#编程-126:WPF初步
C#编程-126:WPF初步
C#编程-126:WPF初步
WPF-ComplexLayout
WPF-ComplexLayout-DockPanel
251 0
WPF-ComplexLayout
|
数据可视化 C#
WPF 中的 NameScope
原文:WPF 中的 NameScope 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:http://blog.csdn.net/wpwalter/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
1006 0
|
C# 图形学 数据格式
WPF中的3D Wireframe
原文:WPF中的3D Wireframe WPF不支持画三维线,但开发人员提供了ScreenSpaceLines3D 类用于实现这个功能。
1307 0
|
C# 前端开发
WPF 小技巧
原文:WPF 小技巧 在使用mvvm模式开发时,对于Command的绑定是一件很伤脑筋的事情,尽管有强大的Blend类库支持: xmlns:Custom="http://www.galasoft.ch/mvvmlight"xmlns:i="http://schemas.
765 0
|
C#
WPF“天狗食月”效果
原文:WPF“天狗食月”效果 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangyisen0713/article/details/18596419 ...
742 0
|
C#
使用WPF实现3D场景[一]
原文:使用WPF实现3D场景[一] 在这篇文章里,将介绍如何实现一个简单的三维场景,一个三维的空间,包括空间内的三维物体的组合. 首先介绍一下一个三维场景里的基本元素: 先是定义一个简单的三维的场景环境 代码如下: 以上是定义了一个名称叫做 myViewport 的的三维场景,接下来可以在这个三位场景里添加一些元素: 元素一:照相机 照相机是三维场景内用户的视角,当然照相机也是唯一的。
1601 0
|
C#
WPF党旗和国徽!
原文:WPF党旗和国徽! 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangyisen0713/article/details/18087007 ...
638 0
|
API C#
WPF版的HideCaret()
原文:WPF版的HideCaret()                                                    WPF版的HideCaret()                                                              ...
983 0