Расширение окна WPF с фиксированной / ограниченной шириной

В моем окне WPF я установил

Width="300" MinWidth="300" MaxWidth="300"

Когда я разворачиваю это окно, оно стыкуется с левой границей экрана с фиксированной кнопкой, но нижняя часть окна находится ПОД панелью задач Windows 8.

я пытался

public MainWindow()
{
    ...
    this.MaxHeight = System.Windows.SystemParameters.WorkArea.Height;
}

, но в результате между панелью задач и моим приложением остается несколько пикселей.

Хотелось бы

  • иметь окно фиксированной ширины
  • прикрепите его к ПРАВОЙ границе на максимальном
  • не закрывать / не заходить под панель задач в развернутом состоянии

person ToastedSoul    schedule 31.07.2013    source источник


Ответы (1)


К сожалению, ваши три требования не кажутся достижимыми с использованием только MinWidth, MaxWidth и WindowState.

Но, тем не менее, добиться чего-то подобного все же возможно. Что вам нужно сделать, так это имитировать развернутое состояние окна. Вам нужно переместить окно в правильное положение, получить нужную высоту и сделать его неподвижным. Первые две части просты, последняя требует более сложных вещей.

Начните с имеющегося у вас окна, задав для Width, MaxWidth и MinWidth значение 300, и добавьте обработчик событий в StateChanged.

Width="300" MinWidth="300" MaxWidth="300" StateChanged="MainWindow_OnStateChanged"

И обработчик событий, и вспомогательные методы:

private bool isMaximized;
private Rect normalBounds;
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
    if (WindowState == WindowState.Maximized && !isMaximized)
    {
        WindowState = WindowState.Normal;
        isMaximized = true;

        normalBounds = RestoreBounds;

        Height = SystemParameters.WorkArea.Height;
        MaxHeight = Height;
        MinHeight = Height;
        Top = 0;
        Left = SystemParameters.WorkArea.Right - Width;
        SetMovable(false);
    }
    else if(WindowState == WindowState.Maximized && isMaximized)
    {
        WindowState = WindowState.Normal;
        isMaximized = false;

        MaxHeight = Double.PositiveInfinity;
        MinHeight = 0;

        Top = normalBounds.Top;
        Left = normalBounds.Left;
        Width = normalBounds.Width;
        Height = normalBounds.Height;
        SetMovable(true);
    }
}

private void SetMovable(bool enable)
{
    HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);

    if(enable)
        source.RemoveHook(WndProc);
    else
        source.AddHook(WndProc);
}

private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    const int WM_SYSCOMMAND = 0x0112;
    const int SC_MOVE = 0xF010;

    switch (msg)
    {
        case WM_SYSCOMMAND:
            int command = wParam.ToInt32() & 0xfff0;
            if (command == SC_MOVE)
                handled = true;
            break;
    }

    return IntPtr.Zero;
}
person AkselK    schedule 31.07.2013