Окно WPF максимизируется с фиксированной / ограниченной шириной

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

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

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

я пытался

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

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

Я бы хотел

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

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;
}
Другие вопросы по тегам