I'm trying to draw a GroupBox
similar to the image below on a dark-colored background.
The first thing I noticed was that also I have chosen a rather dark color #383838
for the border, it still displays a white color! How can I fixed this?
Also can you give some insight on how to achieve the double-border effect displayed in the image below?
Zoomed for better view:
<Window x:Class="WpfApplication13.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources></Window.Resources>
<Grid Background="#535353">
<GroupBox Header="Create New 3D Object"
Foreground="White"
BorderBrush="#383838"
BorderThickness="1"
Width="200"
Height="200"
SnapsToDevicePixels="True"/>
</Grid>
</Window>
What I get:
UPDATE
Using the code below I have achieved the shown result so far:
<Window x:Class="WpfApplication13.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="BorderBrush" Value="#383838" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<Grid SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="6" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="6" />
</Grid.RowDefinitions>
<Border CornerRadius="4" Grid.Row="1" Grid.RowSpan="3" Grid.Column="0" Grid.ColumnSpan="4" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="Transparent" Background="{TemplateBinding Background}" />
<Border Name="Header" Padding="3,1,3,0" Grid.Row="0" Grid.RowSpan="2" Grid.Column="1">
<ContentPresenter ContentSource="Header" RecognizesAccessKey="true" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ContentPresenter Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<Border Grid.Row="1" Grid.RowSpan="3" Grid.ColumnSpan="4" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3">
<Border.OpacityMask>
<MultiBinding Converter="{StaticResource BorderGapMaskConverter}" ConverterParameter="7">
<Binding ElementName="Header" Path="ActualWidth" />
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}" />
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Border.OpacityMask>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Background="#535353">
<GroupBox Header="Create New 3D Object"
Foreground="White"
BorderBrush="#383838"
BorderThickness="1"
Width="200"
Height="200"
SnapsToDevicePixels="True"/>
</Grid>
</Window>
Looks like it's not easy to achieve what you want such as by adjusting some simple properties. You have 2 ways to achieve this:
Edit the current (default) style of the GroupBox
. This is simple but you have to include the custom style into your project.
Create a totally new template for the GroupBox
. This is not easy and requires more works.
I would like to use the first approach. To get (as well as start editing) the current (default) style of the GroupBox
, you can use Blend for Visual Studio, open a new project, drag a GroupBox
on the design surface, right click on the GroupBox
and select Edit Template -> Edit a Copy , you can choose to add a new ResourceDictionary
. After editing the XAML code, you can copy the whole and paste into a ResourceDictionary
file in your project. We can name this file such as CustomStyles.xaml
. We can merge this resource file into Window.Resource
like this:
<Window.Resource>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CustomStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- other resources -->
</ResourceDictionary>
</Window.Resource>
I've edited the default style and here is the result (the content of the CustomStyles.xaml
):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="BorderBrush" Value="#D5DFE5"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<Grid SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="6"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="6"/>
</Grid.RowDefinitions>
<Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="4" Grid.Column="0" CornerRadius="4" Grid.Row="1" Grid.RowSpan="3"/>
<Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="4" CornerRadius="4" Grid.Row="1" Grid.RowSpan="3">
<Border.OpacityMask>
<MultiBinding ConverterParameter="7" Converter="{StaticResource BorderGapMaskConverter}">
<Binding ElementName="Header" Path="ActualWidth"/>
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Border.OpacityMask>
<Border BorderBrush="#ff262626" BorderThickness="1,1,1,1" CornerRadius="0">
<Border BorderBrush="#44ffffff" BorderThickness="0,0,0,1" CornerRadius="0" Margin="0,0,0,-2">
<Border BorderBrush="#44ffffff" BorderThickness="1,1,0,0" CornerRadius="0" Margin="0,0,0,1" />
</Border>
</Border>
</Border>
<Border x:Name="Header" Grid.Column="1" Padding="3,1,3,0" Grid.Row="0" Grid.RowSpan="2">
<ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ContentPresenter Grid.ColumnSpan="2" Grid.Column="1" Margin="{TemplateBinding Padding}" Grid.Row="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
We just edit some properties of the Border
elements above. Note that this kind of 3D effect should have fixed border thickness. Supporting dynamic border thickness may require more complicated editing (moreover we don't know how the border looks when it becomes thicker, maybe the light shadow should be gradient, not just solid). Currently changing the BorderThickness
of the GroupBox
takes no effect, as you can see in the XAML code above, there are 2 borders having BorderBrush
set to Transparent
.