WPF自定义窗口最大化问题

时间:2016-08-02 11:29:10

标签: c# wpf xaml

我是WPF的新手,我正在尝试在Blend中构建一个GUI,但我遇到了各种各样的问题。

我希望我的成品看起来像这样:https://imgur.com/a/BU8Te (红色只是图标的占位符。)

这是我到目前为止的XAML:

<Window x:Class="GUI.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GUI"
        mc:Ignorable="d"
        Title="GUI" 
        Height="840" 
        Width="920"
        WindowStyle="none"
        ResizeMode="CanResizeWithGrip" 
        AllowsTransparency="true"
        MouseLeftButtonDown="Window_MouseLeftButtonDown"
        WindowStartupLocation="CenterScreen"
        Background="Transparent"
        MaxWidth="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Width}"
        MaxHeight="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Height}">
    <Border x:Name="shadow">
        <Grid x:Name="grid" Background="White">
            <Grid.RowDefinitions>
                <RowDefinition Height="20"/>
                <RowDefinition Height="100"/>
                <RowDefinition Height="2"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <Border Grid.Row="0" Background="#F9F9F9" />
            <Border Grid.Row="1" Background="#F9F9F9" />
            <Border Grid.Row="2" Background="#E9E9E9" />


            <DockPanel Grid.Row="0" LastChildFill="False">
                <Button x:Name="btnClose"
                        DockPanel.Dock="Right"
                        VerticalAlignment="Center" 
                        Height="20" Width="20" 
                        Click="btnClose_Click"
                        Style="{DynamicResource CloseButton}">
                    <Path Data="m 357.0883 499.0572 12.62375 12.6275 5.31375 -5.31625 -12.62625 -12.62625 12.62625 -12.61875 -5.31375 -5.3125 -12.62375 12.62 -12.6325 -12.62 -5.30375 5.3125 12.6175 12.61875 -12.6175 12.62625 5.30375 5.31625 12.6325 -12.6275 z" Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,0" ></Path>
                </Button>
                <Button x:Name="btnMaximise"
                        DockPanel.Dock="Right"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        Height="20" Width="20"
                        Click="btnMaximise_Click"
                        Style="{DynamicResource TitleButton}">
                    <Path Data="M4.3685131,23.127279L4.3685131,47.283243 47.117023,47.283243 47.117023,23.127279z M0,10.684L53.755001,10.684 53.755001,51.668001 0,51.668001z M8.5679998,0L58.668022,0 64,0 64,5.6864691 64,45.317999 58.668022,45.317999 58.668022,5.6864691 8.5679998,5.6864691z"
                                        Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,0" ></Path>
                </Button>
                <Button x:Name="btnMinimise"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        DockPanel.Dock="Right"
                        Height="20" Width="20"
                        Click="btnMinimise_Click" 
                        VerticalContentAlignment="Bottom"
                        Style="{DynamicResource TitleButton}">
                    <Button.Content>
                        <Path Data="M0,20L53.333,20 53.333,8.888 0,8.888z"
                                            Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,5"></Path>
                    </Button.Content>
                </Button>
            </DockPanel>
        </Grid>
    </Border>
</Window>

但是当我最大化窗口时,左上角离开我的屏幕(-15,可能是-15?),右下角因为这个原因也太远了。我修改了一些我在网上发现的代码(不记得来源)修复了这个:

private bool isMaximized;
private Rect normalBounds;

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

        normalBounds = RestoreBounds;

        Height = SystemParameters.WorkArea.Height;
        MaxHeight = Height;
        MinHeight = Height;
        Top = 0;
        Left = 0;
        Width = SystemParameters.WorkArea.Width;
        SetMovable(false);
    }
    else if (WindowState == WindowState.Maximized && isMaximized)
    {
        // min
        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;
}

现在它完美无缺,但是我真的很难让它在窗口上使用阴影。当我向窗口添加10px边框并在其上设置Drophadow时,我在边框中获得了调整大小图标,而不是在我的窗口中:

https://imgur.com/a/S9oLK

我还必须修改StateChanged事件方法以在最大化时隐藏边框:

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

        normalBounds = RestoreBounds;

        Height = SystemParameters.WorkArea.Height;
        MaxHeight = Height;
        MinHeight = Height;
        Top = 0;
        Left = 0;
        Width = SystemParameters.WorkArea.Width;
        SetMovable(false);
        this.grid.Margin = new Thickness(0);
        this.BorderThickness = new Thickness(0);
    }
    else if (WindowState == WindowState.Maximized && isMaximized)
    {
        // min
        WindowState = WindowState.Normal;
        isMaximized = false;

        MaxHeight = Double.PositiveInfinity;
        MinHeight = 0;

        Top = normalBounds.Top;
        Left = normalBounds.Left;
        Width = normalBounds.Width;
        Height = normalBounds.Height;
        SetMovable(true);
        this.grid.Margin = new Thickness(10);
        this.BorderThickness = new Thickness(10);
    }
}

但是当窗口被捕捉到屏幕边缘时,这显然不起作用:https://i.imgur.com/pGC1fio.png

总结一下,我的问题是:

  1. 调整大小的抓取器位于边框而不是主窗口。
  2. 当窗口被捕捉到屏幕边缘时,我不知道如何隐藏边框。
  3. 有没有一种简单的方法来解决这个问题?我觉得我必须为所有这些创建一个非常hacky修复,并认为实现这样的自定义窗口要容易得多。

    提前感谢您的帮助。

0 个答案:

没有答案