Граница с эффектом у окна C# WPF

122
17 мая 2021, 03:00

Подскажите пожалуйста, как сделать границу окна, как у Visual Studio 2017.

Вот мой код который переопределяет стиль окна.

<Style x:Key="WindowTemplate" TargetType="{x:Type Window}">
    <Setter Property="WindowStyle" Value="None"/>
    <Setter Property="AllowsTransparency" Value="True"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="WindowChrome.WindowChrome">
        <Setter.Value>
            <WindowChrome ResizeBorderThickness="16" CaptionHeight="32" GlassFrameThickness="1" CornerRadius="0" />
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">
                <Border Padding="7 7 7 5">
                    <Grid TextOptions.TextRenderingMode="ClearType" TextOptions.TextFormattingMode="Display">
                        <Border Width="Auto" Height="Auto" Background="#EFEFF2" Padding="0">
                            <DockPanel HorizontalAlignment="Stretch" Background="Transparent" VerticalAlignment="Stretch">
                                <Border DockPanel.Dock="Top" Background="Transparent" BorderThickness="0">
                                    <Grid Height="32">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="36"/>
                                            <ColumnDefinition />
                                            <ColumnDefinition Width="34"/>
                                            <ColumnDefinition Width="34"/>
                                            <ColumnDefinition Width="34"/>
                                        </Grid.ColumnDefinitions>
                                        <TextBlock Grid.Column="1" HorizontalAlignment="Left"
                                                   VerticalAlignment="Center" Margin="4,0,0,0" FontFamily="Segoe UI"
                                                   FontSize="12" Opacity="0.66" Text="{TemplateBinding Title}"/>
                                        <!--Кнопка для сворачивания окна-->
                                        <Button Grid.Column="2" VerticalAlignment="Top" Width="34" Height="26" WindowChrome.IsHitTestVisibleInChrome="True">
                                            <Grid MaxHeight="9" MaxWidth="9">
                                                <Path Stroke="{TemplateBinding Foreground}" StrokeThickness="1"
                                                      Stretch="None" RenderOptions.EdgeMode="Aliased"
                                                      Data="M0,8 H8 M0,7 H8 M0,6 H8"/>
                                            </Grid>
                                        </Button>
                                        <!--Кнопка для разворачивания окна-->
                                        <Button Grid.Column="3" VerticalAlignment="Top" Width="34" Height="26" WindowChrome.IsHitTestVisibleInChrome="True">
                                            <Grid MaxHeight="9" MaxWidth="9">
                                                <Path Stroke="{TemplateBinding Foreground}" StrokeThickness="1"
                                                      Stretch="None" RenderOptions.EdgeMode="Aliased"
                                                      Data="M0,0 H8 V8 H0 V0 M0,1 H8 M0,2 H8"/>
                                            </Grid>
                                        </Button>
                                        <!--Кнопка закрытия окна-->
                                        <Button Grid.Column="4" VerticalAlignment="Top" Width="34" Height="26" WindowChrome.IsHitTestVisibleInChrome="True">
                                            <Grid MaxWidth="9" MaxHeight="9">
                                                <Path Stroke="{TemplateBinding Foreground}" StrokeThickness="1"
                                                      Stretch="None" RenderOptions.EdgeMode="Aliased"
                                                      Data="M0,0 L8,8 M0,8 L8,0"/>
                                            </Grid>
                                        </Button>
                                    </Grid>
                                </Border>
                                <ContentPresenter/>
                            </DockPanel>
                        </Border>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Но проблема в том что в правой верхней части я не могу изменять размер окна из-за кнопок. И поэтому я хочу сделать такую границу. Я попробовал разные способы но ни один не помог.

Answer 1

Примерно такой стиль:

<Window x:Class="WpfApp1.Views.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"
        mc:Ignorable="d" 
        WindowStyle="None" AllowsTransparency="True"
        Background="Transparent"
        Height="450" Width="800">
    <WindowChrome.WindowChrome>
        <WindowChrome ResizeBorderThickness="7"/>
    </WindowChrome.WindowChrome>
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <ContentPresenter Content="{TemplateBinding Content}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid Margin="5">
        <Border Background="#2D2D30" BorderBrush="#0079CB" BorderThickness=".8">
            <Border.Effect>
                <DropShadowEffect ShadowDepth="0" BlurRadius="5" Color="#0079CB"/>
            </Border.Effect>
        </Border>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="20"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <!--Кнопка для сворачивания окна-->
                <Button Grid.Column="2" VerticalAlignment="Top" Width="34" Height="26" WindowChrome.IsHitTestVisibleInChrome="True">
                    <Grid MaxHeight="9" MaxWidth="9">
                        <Path Stroke="White" StrokeThickness="1"
                                                      Stretch="None" RenderOptions.EdgeMode="Aliased"
                                                      Data="M0,8 H8 M0,7 H8 M0,6 H8"/>
                    </Grid>
                </Button>
                <!--Кнопка для разворачивания окна-->
                <Button Grid.Column="3" VerticalAlignment="Top" Width="34" Height="26" WindowChrome.IsHitTestVisibleInChrome="True">
                    <Grid MaxHeight="9" MaxWidth="9">
                        <Path Stroke="White" StrokeThickness="1"
                                                      Stretch="None" RenderOptions.EdgeMode="Aliased"
                                                      Data="M0,0 H8 V8 H0 V0 M0,1 H8 M0,2 H8"/>
                    </Grid>
                </Button>
                <!--Кнопка закрытия окна-->
                <Button Grid.Column="4" VerticalAlignment="Top" Width="34" Height="26" WindowChrome.IsHitTestVisibleInChrome="True">
                    <Viewbox Width="16" Height="16">
                        <Canvas Width="24" Height="24">
                            <Path Data="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" 
                                  Fill="White" />
                        </Canvas>
                    </Viewbox>
                </Button>
            </StackPanel>
        </Grid>
    </Grid>    
</Window>
  • Убираем у окна все стили, цвета и прочее (WindowStyle="None" AllowsTransparency="True" Background="Transparent"), это позволяет нам задать уже свой стиль для окна.
  • Восстанавливаем возможность перетаскивания, ресайз окна и прочее (WindowChrome).
  • Делаем Grid, который имеет отступ для тени.
  • Внутри сетки делаем отдельный элемент, который будет отвечать за фон, тень и бордюр (у меня это Border.
  • Рядом (не внутри) с Border делаем основную сетку контента, которую размечаем так, как нам нужно (я разместил ваши кнопки).

В итоге мы имеем такое окно:

Это окно успешно меняет размеры со всех углов, ну и работают все кнопки.
Остается только подправить тень, вынести все по своим стилям, поправить кнопки (им стоит не забыть задать Background="Transparent"), а также я бы сделал контенту небольшой отступ в 1-2 пикселя, но это уже мелочи жизни.

READ ALSO
Контейнеризация темплейта aspnetcore-react

Контейнеризация темплейта aspnetcore-react

Недавно начал работать с реактом, решил попробовать реализовать SPA, воспользовавшись темплейтом aspnetcore-react

296
Обмен сообщениями между потоками

Обмен сообщениями между потоками

у меня есть сервер, который создает отдельный поток для каждого клиента

114
Переключения текста в Label

Переключения текста в Label

Подскажите как сделать такого плана переключение текста?

107
Как обновить данные в базе данных

Как обновить данные в базе данных

Я работаю над WPF приложением, в нём есть DataGrid и он связан с базой данныхУ меня есть методы для добавления и удаления данных из Базы и DataGrid

88