I was learning how to change the ControlTemplate and came across this post. I copied the ControlTemplate and created a GroupBox.
<UserControl x:Class="MyTestApp.UserControl1"
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"
mc:Ignorable="d"
d:DesignHeight="130" d:DesignWidth="250">
<Grid>
<Grid.Resources>
<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
<Style x:Key="CheckedGroupBoxStyle" 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.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="6"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="6"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4"/>
<ContentPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="2"/>
<Border Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3" BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4">
<Border.OpacityMask>
<MultiBinding Converter="{StaticResource BorderGapMaskConverter}" ConverterParameter="7">
<Binding Path="ActualWidth" ElementName="Header"/>
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Border.OpacityMask>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
<Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
</Border>
</Border>
<Border x:Name="Header" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Padding="3,1,3,0">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" RecognizesAccessKey="True"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Style="{StaticResource CheckedGroupBoxStyle}">
<GroupBox.Header>
<CheckBox>GroupBox1</CheckBox>
</GroupBox.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="Item A" Grid.Column="0" Grid.Row="0" />
<TextBox Grid.Column="1" Grid.Row="0"></TextBox>
<TextBlock Text="Item B" Grid.Column="0" Grid.Row="1" />
<TextBox Grid.Column="1" Grid.Row="1"></TextBox>
<TextBlock Text="Item C" Grid.Column="0" Grid.Row="2" />
<TextBox Grid.Column="1" Grid.Row="2"></TextBox>
<TextBlock Text="Item D" Grid.Column="0" Grid.Row="3" />
<TextBox Grid.Column="1" Grid.Row="3"></TextBox>
</Grid>
</GroupBox>
</Grid>
</Grid>
</UserControl>
The problem is there is a border around the Grid that's inside the GroupBox. It can be removed by changing Height="Auto" to Height="*" for RowDefinition. If I don't use the CheckedGroupBoxStyle, then the border will not show up either. I want know why because the aforementioned post says the resulting style is almost identical to the default template of the control.
It appears as though you have not added the BorderGapMaskConverter to your code example. After a quick search on MSDN, I found that it is in fact a Converter that is included in the .NET Framework. You can find details of it on the BorderGapMaskConverter Class page. You will be able to use it if you are using .NET 3.0 or above.
UPDATE >>>
No sorry, 'implemented' is no longer the correct word... initially, I thought that you would have to implement your own Converter. However, now that I found out that it is included in the .NET Framework, you just need to add a reference to it in your XAML Resources section like in the example in the other post:
<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
Mind you, you should have had a warning in the Visual Studio Error List saying something like:
The resource "BorderGapMaskConverter" could not be resolved.
Related
I'm trying to make a ControlTemplate to my CustomXamDataGrid class which inherits from infragistics XamDataGrid. I want to show something like a statusbar which indicates how many records are there or selected on the bottom of the XamDataGrid.
I tried some like this:
<Style TargetType="{x:Type controls:CustomXamDataGrid}">
<Setter Property="Background" Value="{StaticResource XamGridBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource XamGridBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:CustomXamDataGrid}">
<Border x:Name="Root" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="PART_ContentHost" />
<ScrollBar x:Name="VerticalScrollBar" Width="22" Grid.Row="0" Grid.Column="1" Style="{StaticResource ScrollBarStyleDoubleArrows}" />
<ScrollBar x:Name="HorizontalScrollBar" Height="16" Grid.Row="2" Style="{StaticResource ScrollBarStyle}" />
</Grid>
<Border Height="25"
Visibility="Visible"
Grid.Row="1"
Margin="0,-1,0,0"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0,1,0,0" SnapsToDevicePixels="True">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Label Content="Total Records: XXX (TODO: Template Binding)" Foreground="Black"/>
<Label Content="Visible Records: XXX (TODO: Template Binding)" Margin="15,0,0,0" Visibility="Visible" Foreground="Black"/>
<Label Content="Selected Records: XXX (TODO: Template Binding)" Margin="15,0,30,0" Foreground="Black"/>
</StackPanel>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It only shows the statusbar properly. The XamDataGrid itself with his calumns and rows are completely empty.
So this is my GroupBox:
<GroupBox
Header="My header"
Background="Transparent"
Foreground="Gainsboro"
BorderBrush="Gainsboro" />
And i have several things that i want to change/issues:
The Foreground is still in black although i have changed it.
My boder around the Header: i want to remove it in order to achieve this kind of style (the header is over the border):
All header is with upper case.
Edit:
After add the style that user #mm8 suggested, this is the results:
Why i can see duplicate border ?
You could override the template for the GroupBox:
<GroupBox Header="My header" Style="{x:Null}">
<GroupBox.Template>
<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="White" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="4" CornerRadius="4" Grid.Row="1" Grid.RowSpan="3">
<Border.OpacityMask>
<MultiBinding ConverterParameter="7">
<MultiBinding.Converter>
<BorderGapMaskConverter />
</MultiBinding.Converter>
<Binding ElementName="Header" Path="ActualWidth"/>
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Border.OpacityMask>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
<Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
</Border>
</Border>
<Border x:Name="Header" Grid.Column="1" Padding="3,1,3,0" Grid.Row="0" Grid.RowSpan="2" Background="LightGreen" BorderBrush="Black" CornerRadius="2" BorderThickness="1">
<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>
</GroupBox.Template>
<TextBlock>content...</TextBlock>
</GroupBox>
Create your own set of controls to have full control, similar to this:
<Grid Width="100" Height="200" Background="DodgerBlue">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border BorderThickness="1" BorderBrush="Gainsboro">
<TextBlock Foreground="Gainsboro">Header</TextBlock>
</Border>
<Border Grid.Row="1" BorderThickness="1" BorderBrush="Gainsboro">
<!--Content-->
</Border>
</Grid>
I'm new to WPF,
I can't align the groupbox header text "abc" to the right,it's stays on the left, don't know why, can anyone help me please?
<Window x:Class="UserInterface.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="500" Width="625">
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="4*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1">
<GroupBox>
<GroupBox.Header>
<DockPanel>
<TextBlock HorizontalAlignment="Right">abc</TextBlock>
</DockPanel>
</GroupBox.Header>
</GroupBox>
</StackPanel>
</Grid>
</Grid>
</Window>
You have to override Template of Groupbox in case you want to align header to Right. By default it is placed at left in default template.
Key is to
Set Grid.ColumnSpan to 2 on border hosting Header ContentPresenter.
Set HorizontalAlignment to Right on ContentPresenter.
Here is the XAML which will work:
<GroupBox Header="abc">
<GroupBox.Template>
<ControlTemplate TargetType="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 BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="4,4,4,4"
BorderBrush="#00FFFFFF"
Background="{TemplateBinding Panel.Background}"
Grid.Column="0"
Grid.Row="1"
Grid.ColumnSpan="4"
Grid.RowSpan="3" />
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="4,4,4,4"
BorderBrush="#FFFFFFFF"
OpacityMask="{x:Null}"
Grid.Row="1"
Grid.ColumnSpan="4"
Grid.RowSpan="3">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="3,3,3,3"
BorderBrush="{TemplateBinding Border.BorderBrush}">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="2,2,2,2"
BorderBrush="#FFFFFFFF" />
</Border>
</Border>
<Border Padding="3,1,3,0"
Name="Header"
Grid.Column="1"
Grid.ColumnSpan="2" <-- HERE
Grid.Row="0"
Grid.RowSpan="2">
<ContentPresenter RecognizesAccessKey="True"
HorizontalAlignment="Right" <-- And HERE
Content="{TemplateBinding HeaderedContentControl.Header}"
ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
ContentStringFormat="{TemplateBinding HeaderedContentControl.HeaderStringFormat}"
ContentSource="Header"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
Margin="{TemplateBinding Control.Padding}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
Grid.Column="1"
Grid.Row="2"
Grid.ColumnSpan="2" />
</Grid>
</ControlTemplate>
</GroupBox.Template>
</GroupBox>
You need to redesign the ContentPresenter inside the template of the Control.
MSDN has an example but somehow it also redesigns the GroupBox.
Check this out and see if thats what you are looking for. You are looking for this line
<ContentPresenter Margin="4"
ContentSource="Header"
RecognizesAccessKey="True" />
Just add to that:
HorizontalAlignment="Right"
I want to achieve such an interface using WPF groupbox control
Is there a way to achieve such an interface with WPF groupbox control?
A simple option is to just overlap the controls and then play around with margins
<Grid>
<GroupBox Header="Title" Margin="0,3,0,0" />
<StackPanel Orientation="Horizontal"
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,0,10,0">
<Button Margin="2" Content="Suchen"/>
<Button Margin="2" Content="Neu"/>
</StackPanel>
</Grid>
If you wanted a re-usable style then you would need to extract the GroupBox's control template and modify that. Something like
<Page.Resources>
<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
<Style x:Key="GroupBoxStyle1" 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 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}"/>
<Border BorderBrush="White" 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="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
<Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
</Border>
</Border>
<StackPanel Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Right" >
<Button Margin="2" Content="Suchen"/>
<Button Margin="2" Content="Neu"/>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid>
<Grid>
<GroupBox Header="Title" Style="{StaticResource GroupBoxStyle1}"></GroupBox>
</Grid>
</Grid>
I needed the same thing, found the answer here:
http://wpf.2000things.com/2013/06/05/835-displaying-custom-content-in-a-groupbox-header/
Don't know which version of .NET
Simple example:
<GroupBox>
<GroupBox.Header>
<StackPanel Orientation="Horizontal">
<Button Content="Click Me"/>
<Button Content="Click Me Too"/>
</StackPanel>
</GroupBox.Header>
<TextBlock Text="Content of box"/>
</GroupBox>
I want to decorate some controls in groups like:
<UserControl x:Class="Infrastructure.UI.ItemsGroup" ... >
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="Red">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="0" />
<TextBlock x:Name="ctrlGroupText" Grid.Row="1" HorizontalAlignment="Center" />
</Grid>
</Border>
</UserControl>
And use it in other XAML-files like:
<Grid Grid.Column="0">
<UI:ItemsGroup GroupText="Hello World">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button>1111</Button>
<Button>1111</Button>
</Grid>
</UI:ItemsGroup>
</Grid>
But it doesn't work. What did I wrong? :)
Thanks
You need to edit the Template for the UserControl instead of adding the Border as the Child
<UserControl x:Class="Infrastructure.UI.ItemsGroup" ... >
<UserControl.Template>
<ControlTemplate TargetType="{x:Type UserControl}">
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="Red">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="0" />
<TextBlock x:Name="ctrlGroupText" Grid.Row="1" HorizontalAlignment="Center" />
</Grid>
</Border>
</ControlTemplate>
</UserControl.Template>
</UserControl>
Update
To set the Text for the TextBlock to GroupText you can use a Binding
<TextBlock x:Name="ctrlGroupText"
Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ItemsGroup}},
Path=GroupText}"
Grid.Row="1"
HorizontalAlignment="Center" />