【问题标题】:LocationChanged is not reliably called when Window is being dragged拖动 Window 时不能可靠地调用 LocationChanged
【发布时间】:2014-11-10 15:35:40
【问题描述】:

为了实现停靠,我依靠监听 Window.LocationChanged 事件来检测在屏幕上拖动的窗口的位置变化。但一位用户报告说,对接无法在他们的机器上运行。

原来他们在 Windows 性能选项中禁用了“拖动时显示窗口内容”,因此 LocationChanged 事件仅在窗口移动到其最终位置时触发,而不是在窗口处于飞行途中时触发。

我想知道是否有另一种方法来检测窗口移动,这是一种不错的方法。我知道我可以调用或连接一些可怕的计时器,但我希望有更好的方法,也许有一个可靠的事件可以收听?

这是一种防止任何“您没有发布任何代码”/“您尝试过什么”投诉的方法。

protected override void OnLocationChanged(EventArgs e)
{

}

【问题讨论】:

  • 我不知道有任何 WPF API 可以检测在这些情况下窗口何时移动。 [Preview]MouseMove 在鼠标悬停在非客户区时不会触发,正如您所观察到的,LocationChanged 只有在切换“拖动时显示窗口内容”时才会触发。您可能需要执行一些 p/invoke 或绘制自己的窗口镶边(但如果您调用 DragMove 来处理窗口拖动,即使这样也可能不起作用)。此外,检查鼠标状态并不能涵盖所有窗口移动——您可以仅使用键盘启动和完成窗口重定位。
  • 我知道我可以 pinvoke 所以就这样做吧。我不认为这里有更好的东西。 pinvoke 也不是什么坏事,实际上它有时是您唯一的解决方案。

标签: c# wpf


【解决方案1】:

这是我的解决方案,

出色的工作。

class MyWindow : Window
{
    private const int WM_MOVING = 0x0216;
    private HwndSource _hwndSrc;
    private HwndSourceHook _hwndSrcHook;

    public MyWindow()
    {
        Loaded += OnLoaded;
        Unloaded += OnUnloaded;
    }

    void OnUnloaded(object sender, RoutedEventArgs e)
    {
        _hwndSrc.RemoveHook(_hwndSrcHook);
        _hwndSrc.Dispose();
        _hwndSrc = null;
    }

    void OnLoaded(object sender, RoutedEventArgs e)
    {
        _hwndSrc = HwndSource.FromDependencyObject(this) as HwndSource;
        _hwndSrcHook = FilterMessage;
        _hwndSrc.AddHook(_hwndSrcHook);
    }

    private IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case WM_MOVING:
                OnLocationChange();
                break;
        }

        return IntPtr.Zero;
    }

    private void OnLocationChange()
    {
        //Do something
    }
}

【讨论】:

    猜你喜欢
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 2020-10-02
    相关资源
    最近更新 更多