【问题标题】:WPF : Move and resize window at once timeWPF:一次移动和调整窗口大小
【发布时间】:2011-10-27 21:44:51
【问题描述】:

在 Win32 API 中,函数 SetWindowPos 提供了一种简单的方法来一次移动和调整窗口大小。

但是,在 WPF 类中 Window 没有像 SetWindowPos 这样的方法。所以我必须编写如下代码:

        this.Left += e.HorizontalChange;
        this.Top += e.VerticalChange;
        this.Width = newWidth;
        this.Height = newHeight;

当然,它运作良好,但并不简单。而且看起来很脏。

如何同时移动窗口和调整大小?

有 API 吗?

【问题讨论】:

    标签: wpf window resize


    【解决方案1】:

    我知道你已经解决了你的问题,但我会发布一个我找到的解决方案,以防它帮助其他人。

    基本上,您必须将 SetWindowsPos 声明为从 Win32 导入的函数,这是签名

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);
    

    该函数需要窗口的 hWnd,为了获得它,您可以在窗口初始化时添加一个处理程序(例如,您可以侦听“SourceInitialized”事件)并将该值存储在班级:

    hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
    

    WPF 管理与设备无关的像素,因此您甚至需要为您的屏幕提供从下降到真实像素的转换器。这是通过以下几行完成的:

    var source = PresentationSource.FromVisual(this);
    Matrix transformToDevice = source.CompositionTarget.TransformToDevice;
    Point[] p = new Point[] { new Point(this.Left + e.HorizontalChange, this.Top), new Point(this.Width - e.HorizontalChange, this.Height) };
    transformToDevice.Transform(p);
    

    终于可以调用SetWindowsPos了:

    SetWindowPos(this.hwndSource.Handle, IntPtr.Zero, Convert.ToInt32(p[0].X), Convert.ToInt32(p[0].Y), Convert.ToInt32(p[1].X), Convert.ToInt32(p[1].Y), SetWindowPosFlags.SWP_SHOWWINDOW);
    

    来源:

    【讨论】:

    • 对此的回答非常好,但我有点惊讶的是 WPF 不支持一次直接移动/调整窗口大小。哇。问题是,我也没有找到更好的“wpf-ish”方式来做这件事。
    • 这应该被标记为正确答案,因为它解决了事件链的根本问题。
    • 我正在学习 WPF,并惊讶于它使一些小任务变得多么困难。必须引用 API DLL 来设置窗口位置是荒谬的。
    • 你说得对,有时 WPF 让我发疯,但是,让我们看看周围,AWT-Swing、QT、GTK、cocoa、android 等。它们都有它们的棘手点,我没有想说 WPF 是我们能拥有的最好的,但就我所见,让我说它还不错;)
    【解决方案2】:

    您可以将代码包装在辅助方法中。就像这样:

    public static class WindowExtensions {
        public static void MoveAndResize( this Window value, double horizontalChange, double verticalChange, double width, double height ) {
            value.Left += horizontalChange;
            value.Top += verticalChange;
            value.Width = width;
            value.Height = height;
        }
    }
    

    所以你的调用代码如下所示:

    this.MoveAndResize( 10, 10, 1024, 768 );
    

    我已经放弃了命名空间和 using 声明,复制时请记住这一点。

    编辑:

    您也可以使用 API。我个人坚持使用托管代码,除非我真的需要使用 API。但这取决于你。

    【讨论】:

    • 毫米。好的。我将使用 API。如你所知,chaing left-top-width-height 连续导致脏外观。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    相关资源
    最近更新 更多