如何用手指而不是鼠标拖动窗口

问题描述:

使用WPF触摸桌面应用程序,如何使用finger而不是鼠标拖动没有标题栏的窗口?

With WPF touch desktop application, how to drag window with no title bar using finger not mouse?

这不是一个问题,而是两个单独的问题。



首先,指点设备软件的设计方式与应用程序在触摸板和鼠标之间没有任何区别。触摸板的工作方式相同,软件通常具有一个特殊功能:您可以通过双击模拟按住鼠标左键,在第二次点击时,用户应保持手指接触,而不是抬起它。在这种情况下,驱动程序不会在第二次单击时将其发送到Windows系统,而是模拟按钮帮助。为Windows和Linux以及可能的其他系统开发了相同的功能。 (我没有触及额外的多点触摸或绘图板功能,这是一个单独的主题。)从Windows子系统和应用程序的角度来看,只有按下按钮,按钮有帮助。



所以,从这一点来说,我们可以忘记鼠标和触摸板之间的区别。



现在,拖动没有非客户端的WPF窗口是与上述无关的完全不同的问题。简短的回答是:您应该处理通常的客户区鼠标事件。这是一个非常容易的问题,因此,我认为你应该尝试解决它,只有在遇到问题并陷入困境时才能提出进一步的问题。







第二,虽然我决定给你一个拖动代码:我有兴趣看看我是否可以从第一次尝试写出来我的头一点点使用不寻常的功能,关闭的影响:

This is not one question, but two separate questions.

First of all, pointing device software is designed the way that an application does not make any difference between a touchpad and mouse. Touchpads works the same way, by the software usually have a special feature: you can simulate holding a left mouse button by double click, when on the second click the user should keep a finger in contact, not lift it. In this case, the driver does not dispatch it to the windows system as the second click and simulated the button help down instead. The same functionality is developed for Windows and Linux, and probably other systems. (I don't touch additional multi-touch or drawing tablet features, which is a separate topic.) From the standpoint of a Windows sub-system and applications, there is only button press and the button is help down.

So, from this point, we can forget the difference between a mouse and a touchpad.

Now, dragging of a WPF window without the non-client are is a completely different question unrelated to the above. The short answer is: you should handle your usual client-area mouse events. This is a really easy problem, so, I think you should try to solve it and ask further questions only if you face problems and get stuck.



On second though, I decided to give you the dragging code: I interested to see if I can write it from the first attempt all from my head using one a little bit unusual feature, the effect of closure:
static void MakeDragging(Window window) {
    bool isDown = false;
    Point position = default(Point);
    window.MouseDown += (sender, eventArgs) => {
        if (eventArgs.LeftButton != MouseButtonState.Pressed) return;
        isDown = true;
        position = window.PointToScreen(eventArgs.GetPosition(window));
    };
    window.MouseUp += (sender, eventArgs) => {
        if (eventArgs.LeftButton != MouseButtonState.Released) return;
        isDown = false;
    };
    window.MouseMove += (sender, eventArgs) => {
        if (!isDown) return;
        Point newPosition = window.PointToScreen(eventArgs.GetPosition(window));
        window.Left += newPosition.X - position.X;
        window.Top += newPosition.Y - position.Y;
        position = newPosition;
    };
} //MakeDragging





比我测试它,它有效。闭包效果适用于变量 isDown position 。在这种方法中,局部变量的行为类似于静态,因为它们用于匿名方法(事件处理程序)。它完全将此代码与任何类型的任何属性隔离开来。请注意,它与方法本身上的 static 修饰符无关,这是因为没有使用实例,以便于显示代码示例。请参阅:

http://en.wikipedia.org/wiki/Closure_%28computer_science %29 [ ^ ]。



请注意,我使用屏幕坐标。不使用它们会产生一个难度:移动窗口位置本身会调用 MouseMove 事件导致意外的递归。



祝你好运,

-SA



Than I tested it, it worked. The closure effect works on the variables isDown and position. In this approach, local variables behave like static, because they are used in anonymous methods (event handlers). It completely isolate this code from the any properties of any types. Note that it has nothing to do with static modifier on the method itself, which is done just because no instance is used, for convenience of showing the code sample. Please see:
http://en.wikipedia.org/wiki/Closure_%28computer_science%29[^].

Note that I use screen coordinates. Not using them would create one difficulty: shifting the window position would itself invoke the MouseMove event causing unwanted recursion.

Good luck,

—SA


当用标题栏拖动窗口时,你是对的,Windows对待两者都是一样的。



如果没有标题栏,程序员必须做一些工作。



'标准'方式用鼠标处理这个是使用DragMove();我试过了。这不适用于触控。正如我所说,Windows代码专门检查鼠标按钮是否关闭 - 如果你不是使用鼠标而是单独使用触摸,那就不是了。



当然WPF以不同的方式处理鼠标和触摸 - 这不是我认为的事实 - 而且很明显 - 鼠标只有一个点而触摸支持许多 - 如果它对待它们相同然后点击和侧面滑动将适用于鼠标就像触摸它一样 - 它显然没有(例如尝试使用Windows 8)。



我所拥有的代码是微不足道的,不起作用 - 例如在触摸事件处理程序中使用DragMove()。



我也尝试在触摸事件处理程序中手动设置窗口的位置 - 导致递归问题和一个疯狂振动的窗口!



我甚至尝试'伪造'鼠标按钮然后使用DragMove()但我坦率地说是在黑暗中拍摄没有运气。
When dragging the window with a title bar, you are right, Windows treats both the same.

Without a title bar the programmer must do some work.

The 'standard' way of handling this with the mouse is to use DragMove(); which I have tried. THis does not work with touch. As I said, the Windows code specifically checks for the mouse button being down - which it is not if you are not using a mouse but using touch alone.

Of course WPF treats mouse and touch in different ways - that's not what I think it is a fact - and it is obvious - a mouse has only a single point whereas touch supports many - if it treated them identically then a click and sideways swipe would work with teh mouse as it does with touch - which it plainly doesn't (try using Windows 8 for example).

The code I have is trivial and doesn't work - using DragMove() in a touch event handler for example.

I also tried setting the position of the window manually in the touch down event handler - buit that led to recursive issues and a wildly-vibrating window!

I even tried 'faking' a mousebutton down and then using DragMove() but i frankly was shooting in teh dark here and had no luck.