Expander in Grid does not collapse - wpf

I want my Expandercolumn to take 30% width when expanded. I also want the column of the Expander to shrink when collapsed and the other grids to increase size while keeping their proportion.
Aside of some margin I want Column 1: 30% Column 2 and 3 to have 35% each
I thought I need an auto column for the Expander, but then nothing tells it what proportions it should have. If I set a proportion, it does either not shrink the Expanderand if I change the alignments, I can't get the right combination.
This is my current code. The rectangles are just placeholders.
<Grid>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
<RowDefinition Height="2.5*"/>
<RowDefinition Height="0.2*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="0.3*" />
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Expander Background="Crimson" IsExpanded="False" ExpandDirection="Right" Grid.Row="1"
Grid.RowSpan="2" Grid.Column="1" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Rectangle Fill="Aquamarine" Width="Auto" HorizontalAlignment="Stretch"/>
</Expander>
<Rectangle Height="Auto" Fill="Coral" Width="Auto" Grid.Row="2" Grid.Column="3" />
<Rectangle Height="Auto" Fill="DarkOliveGreen" Width="Auto" Grid.Row="2" Grid.Column="2"/>
</Grid>

You can create a style for the ColumnDefinition in question that:
Sets the Width to 0.3* when the Expander is expanded
Sets the Width to Auto, when it is collapsed.
Assign an x:Name to the Expander and use a DataTrigger in the style that binds the IsExpanded property of Expander with ElementName syntax. Use a setter for the default Width value.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
<RowDefinition Height="2.5*"/>
<RowDefinition Height="0.2*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition>
<ColumnDefinition.Style>
<Style TargetType="{x:Type ColumnDefinition}">
<Setter Property="Width" Value="0.3*"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsExpanded, ElementName=MyExpander}" Value="False">
<Setter Property="Width" Value="Auto"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ColumnDefinition.Style>
</ColumnDefinition>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Expander x:Name="MyExpander" Background="Crimson" IsExpanded="False" ExpandDirection="Right" Grid.Row="1"
Grid.RowSpan="2" Grid.Column="1" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Rectangle Fill="Aquamarine" Width="Auto" HorizontalAlignment="Stretch"/>
</Expander>
<Rectangle Height="Auto" Fill="Coral" Width="Auto" Grid.Row="2" Grid.Column="3" />
<Rectangle Height="Auto" Fill="DarkOliveGreen" Width="Auto" Grid.Row="2" Grid.Column="2"/>
</Grid>
Collapsed Expander.
Expanded Expander.

Related

Tab-shaped border needs clipping

I have a spec for an application with three columns where the central one bows in into an inverted tab shape.
I have the basics figured out:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="371*"></ColumnDefinition>
<ColumnDefinition Width="469*"></ColumnDefinition>
<ColumnDefinition Width="371*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="83*"></RowDefinition>
<RowDefinition Height="309*"></RowDefinition>
<RowDefinition Height="223*"></RowDefinition>
<RowDefinition Height="67*"></RowDefinition>
</Grid.RowDefinitions>
<TextBox Background="Transparent" Grid.Row="0"
Text="Foo" HorizontalAlignment="Center" VerticalAlignment="Center" >
</TextBox>
<Border Grid.Row="0" BorderBrush="Red" BorderThickness="0,0,0,4"></Border>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="221*"></RowDefinition>
<RowDefinition Height="171*"></RowDefinition>
<RowDefinition Height="290*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
</Grid>
<Border Grid.Row="0" BorderBrush="Red" BorderThickness="4,0,4,4" CornerRadius="50" >
</Border>
</Grid>
</Grid>
But the inverted tab border is in need of clipping about 60% of the way down. I can of course position an element on top of it but that seems like the wrong solution and I'd like to avoid it.
I've looked at the Border.Clip property but can't quite figure out how to work with it nor find much in the way of documentation. What do I need to do here?
There's a bunch of different ways you can accomplish this, some will be more appropriate for potential resizing considerations than others etc. Here's just a few potential solution examples.
<StackPanel>
<!-- added -->
<Grid Background="LightBlue" Height="100">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="2"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Grid.ColumnSpan="3"
Fill="DarkBlue"/>
<Rectangle Grid.Row="1" Grid.ColumnSpan="3"
Fill="Yellow"/>
<Border Grid.Row="1" Grid.RowSpan="2" Grid.Column="1"
Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="2,0,2,2"
CornerRadius="0,0,20,20"/>
</Grid>
<!-//-->
<Grid Background="LightBlue" Height="100">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Grid.ColumnSpan="3"
Fill="DarkBlue"/>
<Rectangle Grid.ColumnSpan="3" VerticalAlignment="Bottom" Height="2"
Fill="Yellow"/>
<Border Grid.Row="1" Grid.RowSpan="2" Grid.Column="1"
Background="DarkBlue" Margin="0,-2,0,0"
BorderBrush="Yellow" BorderThickness="2,0,2,2"
CornerRadius="0,0,20,20"/>
</Grid>
<!-- Or another, or another, or another... -->
<Grid Background="LightBlue" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="3" Height="50"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="0,0,0,2"/>
<Border Grid.Column="1" Height="80" CornerRadius="20"
VerticalAlignment="Top" Background="DarkBlue" BorderThickness="2,0,2,2">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="DarkBlue" Offset="0.6"/>
<GradientStop Color="#FFFFFF00" Offset="0.6"/>
</LinearGradientBrush>
</Border.BorderBrush>
</Border>
</Grid>
<Grid Background="LightBlue" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.Column="1" Height="80" CornerRadius="20"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="2,0,2,2"/>
<Border Grid.ColumnSpan="3" Height="50"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="0,0,0,2"/>
<Rectangle Grid.Column="1" Height="51" Margin="2,0"
VerticalAlignment="Top" Fill="DarkBlue"/>
</Grid>
<Grid Background="LightBlue" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="3" Height="50"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="0,0,0,2"/>
<Border Grid.Column="1" Height="80" CornerRadius="20"
VerticalAlignment="Top" Background="DarkBlue"
BorderBrush="Yellow" BorderThickness="2,0,2,2"
Clip="M0,47.7 L175,47.7 L175,80 L0,80 z"/>
</Grid>
</StackPanel>
CornerRadius has a constructor that can take 4 values for the radius of each corner: top-left, top-right, bottom-right, bottom-left.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="9*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Background="Transparent" Grid.Row="0" Grid.Column="0"
Text="Foo" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Border Grid.Row="1" Grid.Column="1" BorderBrush="Red" BorderThickness="4,0,4,4" CornerRadius="0, 0, 50, 50" />
</Grid>
Another option (probably the one I would choose) is to use a TabControl, put the tab on the bottom and center it.
<TabControl TabStripPlacement="Bottom" Background="DarkBlue" BorderBrush="Yellow" Margin="3" >
<TabControl.Resources>
<Style TargetType="{x:Type TabPanel}">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</TabControl.Resources>
<TabItem Header="Test" Background="DarkBlue" BorderBrush="Yellow" Foreground="Yellow" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="1" Text="Foo" />
</Grid>
</TabItem>
</TabControl>

Set TextBlock width to 100% inside DataTemplate in Windows Store app

I have this XAML and having problems with grid width.
<DataTemplate x:Key="FormTileItemTemplate">
<Grid Height="70" Background="#FFECECEC">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="38" />
</Grid.ColumnDefinitions>
<StackPanel Margin="10,0,20,15" VerticalAlignment="Bottom">
<TextBlock Text="{Binding FormName}" Foreground="Black" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="0" FontSize="34.667" FontWeight="Light" LineHeight="32" />
</StackPanel>
<Grid Grid.Column="1">
<Image Stretch="UniformToFill" Source="/Assets/Images/FormCompleteRed.png" />
</Grid>
</Grid>
</DataTemplate>
<Grid x:Name="itemFormsGrid" Margin="0,60,0,50">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Margin="0,0,20,0" Width="100" Height="100" Source="/Assets/Images/session-forms.png" Stretch="UniformToFill" HorizontalAlignment="Right" />
<ListView
x:Name="formListView"
Grid.Row="1"
IsSwipeEnabled="False"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource FormTileItemTemplate}"
d:DataContext="{Binding Path=SessionForms, Source={d:DesignInstance Type=SampleData:SessionReviewDesignDataSource, IsDesignTimeCreatable=True} }"
Margin="0,20,0,0" />
</Grid>
Here is the output. Output
But I need the TextBlock to stretch way up to right. Appreciate any help.
Set HorizontalContentAlignment property like below to stretch the ListViewItems
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>

User control inside ScrollViewer doesn't scroll in WPF

I have the following code (abbreviated) in my main window:
Although I set both scroll bar visibilities and CanContentScroll properties it doesn't scroll. I assume it has to do with my user control.
<Window>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TabControl Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" Margin="0" VerticalAlignment="Stretch" Height="Auto" Width="Auto">
<TabItem Header="TEST">
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<my:MY_USER_CONTROL x:Name="myUserControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScrollViewer.CanContentScroll="True" />
</ScrollViewer>
</TabItem>
</TabControl>
<Button Grid.Column="0" Grid.Row="2" >a button</Button>
<WrapPanel Grid.Column="0" Grid.Row="3" >
</WrapPanel>
</Grid>
</Window>
Abbreviated structure of my user control:
<UserControl>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="183*" />
<ColumnDefinition Width="117*" />
</Grid.ColumnDefinitions>
<TreeView ItemsSource="{Binding Children}" Grid.ColumnSpan="2">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.Children>
<TextBlock Background="LightGray" Padding="2" Margin="2" Grid.Row="0" Grid.Column="0" Text="{Binding Name}" />
<TextBlock Padding="2" Margin="2" Grid.Row="0" Grid.Column="1" Text="{Binding Content}" />
</Grid.Children>
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</UserControl>
You need to set it like this. I changed the RowDefinition for Row0 to Height="*" So it will use as much space it can. Then changed place between the ScrollViewer and the TabControl. So the TabControl is a content of the ScrollViewer.
<Window>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Grid.Column="0" Grid.Row="0">
<TabControl HorizontalAlignment="Stretch" Margin="0" VerticalAlignment="Stretch"
Height="Auto" Width="Auto">
<TabItem Header="TEST">
<my:MY_USER_CONTROL x:Name="myUserControl"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ScrollViewer.CanContentScroll="True" />
</TabItem>
</TabControl>
</ScrollViewer>
<Button Grid.Column="0" Grid.Row="2" >a button</Button>
<WrapPanel Grid.Column="0" Grid.Row="3" >
</WrapPanel>
</Grid>
When you set CanContentScroll to True, the ScrollViewer assumes that your content implements IScrollInfo (which i guess doesn´t).
Try setting CanContentScroll on the ScrollViewer to false, this allows the content to use as much space as it wants and the ScrollViewer takes care of scrolling.
However, depending on the size, number of visuals etc. of your control, this might become a performance issue (e.g. no UI Virtualization when CanContentScroll is set to False).
Looks like the content inside your scrollviewer is the same size as the viewer so there is nothing to scroll?
if you do something like
<ScrollViewer HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid Background="Red">
</Grid>
</ScrollViewer>
Then the grid is the same size as the scroll viewer and will never allow scrolling, if you set the height of the grid to more than the viewer can display you'll get a scroller.
<ScrollViewer HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid Background="Red" Height="500">
</Grid>
</ScrollViewer>

How to add spacing between the listview.items?

I would like to add distance between its items, so I can lead my bind operation on it.
<ListView Margin="0,22,0,0" x:Name="ListViewImages" MouseLeftButtonDown="ListViewImages_MouseLeftButtonDown"
SelectionMode="Extended" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled" local:ListBoxExtention.IsRectSelectionEnabled="True">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Name="WraPanel1" Margin="5" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="5" ></RowDefinition>
<RowDefinition Height="150"></RowDefinition>
<RowDefinition Height="15" ></RowDefinition>
<RowDefinition Height="5" ></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7" x:Name="columnLeft"></ColumnDefinition>
<ColumnDefinition Width="100" x:Name="columnImage"></ColumnDefinition>
<ColumnDefinition Width="7" x:Name="columnRight"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Name="Grid_Images" AllowDrop="True" Width="Auto" Height="Auto" Tag="{Binding Id}" Source="{Binding Converter={StaticResource imageConverter}}" Grid.Row="1" Grid.Column="1"
DragEnter="Grid_Images_DragEnter" MouseLeftButtonDown="Grid_Images_MouseLeftButtonDown" MouseLeftButtonUp="Grid_Images_MouseLeftButtonUp"
MouseMove="Grid_Images_MouseMove" Drop="Grid_Images_Drop" KeyUp="Grid_Images_KeyUp" />
<TextBlock Name="Grid_Descrition" AllowDrop="True" TextAlignment="Center" Text="{Binding Id}" Grid.Row="2" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Hopefully this will save someone else time. I found there are multiple properties that have to be set to 0 in order to completely remove the spacing between ListViewItems in a ListView control. In addition to Margin and Padding I had to set the BorderThickness to 0.
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
</Style>
</ListView.ItemContainerStyle>
You can just add some Margin to your grid
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="5" ></RowDefinition>
<RowDefinition Height="150"></RowDefinition>
<RowDefinition Height="15" ></RowDefinition>
<RowDefinition Height="5" ></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7" x:Name="columnLeft"></ColumnDefinition>
<ColumnDefinition Width="100" x:Name="columnImage"></ColumnDefinition>
<ColumnDefinition Width="7" x:Name="columnRight"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Name="Grid_Images" AllowDrop="True" Width="Auto" Height="Auto" Tag="{Binding Id}" Source="{Binding Converter={StaticResource imageConverter}}" Grid.Row="1" Grid.Column="1"
DragEnter="Grid_Images_DragEnter" MouseLeftButtonDown="Grid_Images_MouseLeftButtonDown" MouseLeftButtonUp="Grid_Images_MouseLeftButtonUp"
MouseMove="Grid_Images_MouseMove" Drop="Grid_Images_Drop" KeyUp="Grid_Images_KeyUp" />
<TextBlock Name="Grid_Descrition" AllowDrop="True" TextAlignment="Center" Text="{Binding Id}" Grid.Row="2" Grid.Column="1"/>
</Grid>
Add a ListView.ItemContainerStyle and create a Setter that applies a Margin of whatever size you prefer.

Style each datagrid column header

I want to add another row to the HeaderRow and for each column insert specific control.
This is my code where add this row, but I can only set same control (in this case textbox) for every column, but I want to set specific control for specific column.
(like it's done in ASP.NET repeater)
<Style x:Key="DataGridColumnHeaderStyle1" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid x:Name="grid" VerticalAlignment="Center" HorizontalAlignment="Stretch" Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="ColumnHeader" Grid.Row="0" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Height="18" />
<Grid Grid.Row="1">
<TextBox Text="" HorizontalAlignment="Stretch" BorderThickness="0,1,1,1" />
</Grid>
</Grid>
</Style>
You can Make use of the HeaderTemplate to specify different datatemplates for each Column
Sample
<Window.Resources>
<DataTemplate x:Key="Template1">
<Grid x:Name="grid" VerticalAlignment="Center" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="ColumnHeader" Text="Student Id" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Height="18" />
<Grid Grid.Row="1">
<TextBox Text="" HorizontalAlignment="Stretch" BorderThickness="0,1,1,1" />
</Grid>
</Grid>
</DataTemplate>
<DataTemplate x:Key="Template2">
<Grid x:Name="grid" VerticalAlignment="Center" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="ColumnHeader" Text="Student Name" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Height="18" />
<Grid Grid.Row="1">
<TextBox Text="" HorizontalAlignment="Stretch" BorderThickness="0,1,1,1" />
</Grid>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<DataGrid Name="dataGrid" >
<DataGrid.Columns>
<DataGridTextColumn HeaderTemplate="{StaticResource Template1}" Width="90*" MinWidth="120" Binding="{Binding StudentId}"/>
<DataGridTextColumn HeaderTemplate="{StaticResource Template2}" Width="90*" MinWidth="120" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Score" Width="100*" MinWidth="150" Binding="{Binding Score}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
I approached this a little bit different, I styled DataGridColumnHeadersPresenter, it allows me to syle the column headers row (instead of column header).
There I add my new row and all the controls I need, I alsoe set the width of every cell to match the width of it's header .
<Style x:Key="DataGridColumnHeadersPresenterStyle1" TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DataGridColumnHeader x:Name="PART_FillerColumnHeader" IsHitTestVisible="False"/>
<ItemsPresenter/>
<Grid Grid.Row="1" VerticalAlignment="Top" HorizontalAlignment="Left" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ActualWidth, ElementName=Col1}"/>
<ColumnDefinition Width="{Binding ActualWidth, ElementName=Col2}"/>
<ColumnDefinition Width="{Binding ActualWidth, ElementName=Col3}"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Bottom" Width="Auto" Height="25" BorderThickness="1,2,0,2"/>
my other controls go here
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>

Resources