WPF WindowChrome: края максимизированного окна выходят из экрана

Я использую WindowChrome для настройки окна. Когда я максимизирую окно, то края не отображаются на экране. Для этого я использую следующий код:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="50" CornerRadius="0" GlassFrameThickness="0" NonClientFrameEdges="None" ResizeBorderThickness="5" UseAeroCaptionButtons="False" />
    </WindowChrome.WindowChrome>

    <Grid>  
        <Grid.Style>
            <Style TargetType="{x:Type Grid}">
                <Setter Property="Margin" Value="0" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=WindowState}" Value="Maximized">
                        <Setter Property="Margin" Value="{x:Static SystemParameters.WindowResizeBorderThickness}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Grid.Style>
        <Border BorderThickness="2" BorderBrush="Blue" Background="Yellow" />
    </Grid>

</Window>

Моя проблема: как я могу получить правильное количество пикселей, чтобы ребра не выходили из экрана.

SystemParameters.WindowResizeBorderThickness содержит не правильное значение.

Ответ 1

WindowChrome будет в основном перекрываться размером ResizeBorderThickness при максимизации.

Если вы хотите, чтобы ваше окно было полностью видимым при максимизации, просто используйте WindowChrome ResizeBorderThickness (5px) качестве Margin в стиле сетки:

<Setter Property="Margin" Value="5" />

В противном случае, если вы хотите, чтобы BorderThickness не был виден, пока окно развернуто, вы должны использовать Border BorderThickness (2px) качестве Margin в дополнение к WindowChrome ResizeBorderThickness (5px) в стиле Grid. Тогда Margin будет 7px.

Ответ 2

Пример того, как увеличить толщину границы, когда окно развернуто. В противном случае из-за странностей WindowChrome часть границы исчезнет.

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

<Window ResizeMode="CanResizeWithGrip"
        WindowStyle="SingleBorderWindow">
    <!-- Remove window header and border. Use with ResizeMode="CanResizeWithGrip" and WindowStyle="SingleBorderWindow". -->
    <WindowChrome.WindowChrome>
        <WindowChrome     
            CaptionHeight="1"  
            CornerRadius ="0"
            ResizeBorderThickness="4"         
            GlassFrameThickness="0">
        </WindowChrome>
    </WindowChrome.WindowChrome>            
    <Border BorderThickness="1">     
        <Border.Style>
            <Style TargetType="{x:Type Border}">
                <Style.Triggers>
                    <!-- Add to avoid border disappearing when window is maximised -->
                    <DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource AncestorType=Window}}" 
                                 Value="Maximized">
                        <Setter Property="Margin" Value="10"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource AncestorType=Window}}" 
                                 Value="Normal">
                        <Setter Property="Margin" Value="0"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
        <Grid>
           <!-- Window XAML here. -->
        <Grid>
     </Border>
 </Window>

Ответ 3

Исходя из оригинального примера ОП, они были почти там...

Когда окно развернуто, Windows, кажется, игнорирует значение ResizeBorderThickness. Использование <Setter Property="Margin" Value="7"/> кажется, работает, но это значение может потребоваться изменить в зависимости от операционной системы (я проверял это на Windows 10).

Я рекомендую сделать несколько небольших изменений (см. Код ниже), таких как добавление WindowStyle="None" и ResizeMode="CanResize" в Window, а также перемещение Style в Window.Resources, Application.Resources или даже в ResourceDictionary, изменив стиль TargetType на "{x:Type Panel}" и используя имя ключа (например: x:Key="WindowMainPanelStyle"), так как это предотвратит автоматическое применение стиля к любым дочерним элементам Grid, а также разрешить использование стиля со всеми элементами, которые наследуются от Panel (например, Border, DockPanel, Grid, StackPanel и т.д.).

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    WindowStyle="None"
    ResizeMode="CanResize">

<WindowChrome.WindowChrome>
    <WindowChrome CaptionHeight="50" ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>

<Window.Resources>
    <Style TargetType="{x:Type Panel}" x:Key="WindowMainPanelStyle">
        <Setter Property="Margin" Value="0" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=WindowState}" Value="Maximized">
                <Setter Property="Margin" Value="7" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid Style="{StaticResource WindowMainPanelStyle}">
    <Border BorderThickness="2" BorderBrush="Blue" Background="Yellow" />
</Grid>

</Window>