WPF: переместить и изменить размер окна одновременно - PullRequest
4 голосов
/ 16 августа 2011

В Win32 API функция SetWindowPos обеспечивала простой способ перемещения и изменения размера окна одновременно.

Однако в классе WPF Window нет метода, подобного SetWindowPos.Поэтому я должен написать следующее:

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

Конечно, это работает хорошо, но это не просто.И выглядит грязно.

Как я могу переместить окно и изменить размер сразу?

Есть ли API?

Ответы [ 2 ]

7 голосов
/ 29 февраля 2012

Я знаю, что вы уже решили свою проблему, но я опубликую найденное мной решение, если оно поможет другим.

В основном, Вы должны объявить, что 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);

Источники:

1 голос
/ 16 августа 2011

Вы можете обернуть ваш код вспомогательным методом. Просто так:

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 );

Я остановил пространство имен и, используя объявление, помните об этом при копировании.

Edit:

Вы также можете использовать API. Лично я придерживаюсь управляемого кода, если мне действительно не нужно использовать API. Но это зависит от вас.

...