【问题标题】:WPF window maximize with fixed/limited widthWPF窗口以固定/有限宽度最大化
【发布时间】:2013-07-31 13:10:23
【问题描述】:

在我的 WPF 窗口中,我设置了

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

当我最大化这个窗口时,它会停靠在屏幕的左边框上,但窗口的底部位于 Windows 8 任务栏的下方。

我试过了

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

,但这会导致任务栏和我的应用程序之间出现几个像素的可用空间。

我愿意

  • 有一个固定宽度的窗口
  • 将其停靠在最大化时的右边框
  • 在最大化状态下不覆盖/进入任务栏下方

【问题讨论】:

    标签: wpf windows-8 maximize


    【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      • 1970-01-01
      • 1970-01-01
      • 2015-03-31
      • 2015-04-14
      相关资源
      最近更新 更多