【问题标题】:Way to make a Windowless WPF window draggable without getting InvalidOperationException使无窗口 WPF 窗口可拖动而不会出现 InvalidOperationException 的方法
【发布时间】:2011-03-17 11:45:03
【问题描述】:

我有一个无边框的 WPF 主窗口。我正在努力让最终用户可以拖动窗口。

我在 Window 的构造函数中添加了以下内容:

this.MouseLeftButtonDown += delegate { DragMove(); };

问题是,我有一个带有两个按钮的对话框。当我单击其中一个按钮时,我会收到未处理的 InvalidOperationException 消息“只能在鼠标主按钮按下时调用 DragMove。”

这提出了几个问题: 为什么对话框中的 mousedown 事件与此有关? 如果没有这个例外,我该怎么做?

谢谢!

【问题讨论】:

  • 我也有带按钮的无边框窗口,让用户通过按鼠标左键拖动它,它工作正常。请提供显示此行为的最小但完整的代码示例。

标签: wpf windowless


【解决方案1】:

使无边框窗口可移动的“正确”方法是在 WM_NCHITTEST 消息中返回 HTCAPTION。以下代码显示了如何做到这一点。请注意,如果光标位于 Window 的某些可视元素上,您将希望返回 HTCLIENT,因此此代码只是为了帮助您入门。

http://msdn.microsoft.com/en-us/library/ms645618(VS.85).aspx

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    protected override void OnSourceInitialized(EventArgs e)
    {
        HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(this);
        hwndSource.AddHook(WndProcHook); 
        base.OnSourceInitialized(e);
    }

    private static IntPtr WndProcHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handeled)
    {
        if (msg == 0x0084) // WM_NCHITTEST
        {
            handeled = true;
            return (IntPtr)2; // HTCAPTION
        }
        return IntPtr.Zero;
    }
}

【讨论】:

  • 如果您尝试按照 Tergiver 的建议“在 WM_NCHITTEST 消息中返回 HTCAPTION”,则按钮将不可点击,即点击事件将不适用于按钮。有没有人可以解决这个问题?
  • 请注意,我声明该代码只是一个起点。您不能像上面的代码那样为窗口的整个矩形返回 HTCAPTION。您必须决定窗口的哪些区域不应该是“标题”区域。这可能就像控制区域中的矩形一样简单,也可能像遍历可视化树并查找控件一样复杂。
【解决方案2】:

有一个微软项目可以处理所有“无窗口”风格等等,它是开源的,你可能想看看http://code.msdn.microsoft.com/WPFShell。我正在使用商业金融应用程序,并且在任何版本的 Windows 上都没有遇到任何问题。

【讨论】:

    【解决方案3】:

    设置窗口的 MouseDown 属性或您要使用的任何其他控件:

    <TextBlock Grid.Column="0" HorizontalAlignment="Stretch"  MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" >Handy Dandy</TextBlock>
    

    并在后面的代码中这样实现:

    private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
         this.DragMove();
    }
    

    发件人:http://www2.suddenelfilio.net/2007/01/19/wpf-draggable-windowless-windows/

    【讨论】:

      【解决方案4】:

      你可以覆盖原来的方法:

       public new void DragMove()
           {
              if (this.WindowState == WindowState.Normal)
              {
                  SendMessage(hs.Handle, WM_SYSCOMMAND, (IntPtr)0xf012, IntPtr.Zero);
                  SendMessage(hs.Handle, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-25
        • 2014-07-07
        • 1970-01-01
        • 2011-07-26
        • 2016-10-09
        • 2018-10-13
        • 1970-01-01
        • 2016-02-03
        相关资源
        最近更新 更多