管理双屏幕的最大化功能

时间:2016-07-13 12:15:44

标签: c# wpf window

我正在开发一个与多屏幕兼容的多窗口应用程序。我为所有窗户制作了自己的标题栏。

我的标题栏:

<Grid x:Class="TitleBar"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      Style="{DynamicResource TitleStyle}"
      MouseLeftButtonDown="gridBar_MouseLeftButtonDown"
      x:Name="titleBar">

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="auto"/>
    </Grid.ColumnDefinitions>

    <Label Grid.Column="0" [...]/>

    <Button Grid.Column="1" x:Name="bttnClose" [...]/>
    <Button Grid.Column="1" x:Name="buttonMinimize" [...]/>
</Grid>

使用功能:

private void gridBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (Window.GetWindow(this) != null)
    {
        if (e.ClickCount == 2) // double click handle
        {
            if (Window.GetWindow(this).WindowState == WindowState.Normal)                   
                Window.GetWindow(this).WindowState = WindowState.Maximized;
            else
                Window.GetWindow(this).WindowState = WindowState.Normal;
        }
        try
        {
            Window.GetWindow(this).DragMove();
        }
        catch { }
    }
}

除主窗口外,我的所有窗口都不可调整大小(最大/最小高度和宽度相等)。所以我想管理全屏到多屏幕环境。

我在MainWindow班级上添加了此内容:

protected override void OnStateChanged(EventArgs e)
{
    if (WindowState == WindowState.Maximized)
    {
        var hwnd = new System.Windows.Interop.WindowInteropHelper(this).EnsureHandle();
        var currentMonitor = NativeMethods.MonitorFromWindow(hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST);
        var primaryMonitor = NativeMethods.MonitorFromWindow(IntPtr.Zero, NativeMethods.MONITOR_DEFAULTTOPRIMERTY);
        var isInPrimary = currentMonitor == primaryMonitor;

        // Don't want to hide the taskbar
        if (isInPrimary)
            this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
        else
            this.MaxHeight = Double.PositiveInfinity;
    }
    base.OnStateChanged(e);
}

internal static class NativeMethods
{
    public const Int32 MONITOR_DEFAULTTOPRIMERTY = 0x00000001;
    public const Int32 MONITOR_DEFAULTTONEAREST = 0x00000002;

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern IntPtr MonitorFromWindow(IntPtr handle, Int32 flags);
}

它几乎可以工作,但是当我设置MaxHeight时,它不会刷新实际的Height。我必须通过屏幕最大化两次以获得正确的大小。

你能帮助我吗?

1 个答案:

答案 0 :(得分:0)

我终于找到了解决方案,但也许不是最好的解决方案:

private void Maximize()
{
    var hwnd = new System.Windows.Interop.WindowInteropHelper(this).EnsureHandle();
    var currentMonitor = NativeMethods.MonitorFromWindow(hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST);
    var primaryMonitor = NativeMethods.MonitorFromWindow(IntPtr.Zero, NativeMethods.MONITOR_DEFAULTTOPRIMERTY);
    var isInPrimary = currentMonitor == primaryMonitor;

    // Don't want to hide the taskbar
    if (isInPrimary)
        this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
    else
        this.MaxHeight = Double.PositiveInfinity;
}

protected override void OnStateChanged(EventArgs e)
{
    if (WindowState == WindowState.Maximized && DoRefresh)
    {
        DoRefresh = false;
        WindowState = WindowState.Normal;
        Maximize();
        DoRefresh = true;
    }
}

问题是在最大化的Windows上更改高度或MaxHeight无效。当状态更改为Maximized I时,将其强制为正常并更改MaxHeight。之后我将状态重置为最大化。我创建了bool DoRefresh以避免无限循环。