In a DataGrid I have added an Expander to the row headers, which works fine functionally, however when expanded it centers vertically.
I would like it to remain at the top of the header where it was clicked in the first place.
What am I missing here?
<DataGrid Name="dgAudit"
CanUserReorderColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserResizeColumns="False"
CanUserResizeRows="False"
CanUserSortColumns="False"
IsReadOnly="True"
ItemsSource="{Binding GEOM_ASSET_OC_LIST}"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
AutoGenerateColumns="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
RowDetailsVisibilityMode="Collapsed"
>
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<Expander Template="{StaticResource NewExpander}"
OverridesDefaultStyle="True"
Header=""
HorizontalAlignment="Right"
VerticalAlignment="Top"
Expanded="Expander_Expanded" Collapsed="Expander_Collapsed"
>
</Expander>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
<DataGrid.Columns>...
Here is the main template:
<ControlTemplate x:Key="NewExpander" TargetType="{x:Type Expander}">
<DockPanel>
<ToggleButton x:Name="ExpanderButton"
DockPanel.Dock="Top"
Template="{StaticResource AnimatedExpanderButtonTemp}"
Content="{TemplateBinding Header}"
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
OverridesDefaultStyle="True"
Padding="0.5,0">
</ToggleButton>
</DockPanel>
</ControlTemplate>
Here is the template for animation:
<ControlTemplate x:Key="AnimatedExpanderButtonTemp" TargetType="{x:Type ToggleButton}">
<Border x:Name="ExpanderButtonBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="Transparent"
Grid.ColumnSpan="2"/>
<Ellipse Name="Circle"
Grid.Column="0"
Stroke="DarkGray"
Fill="LightGray"
Width="15"
Height="15"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
<Path x:Name="Arrow"
Grid.Column="0"
Data="M 1,1.5 L 4.5,5 8,1.5"
Stroke="#FF666666"
StrokeThickness="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RenderTransformOrigin="0.5,0.5" >
<Path.RenderTransform>
<RotateTransform Angle="0"/>
</Path.RenderTransform>
</Path>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Arrow"
Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)"
To="180"
Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Arrow"
Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)"
To="0"
Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" Value="#FF3C7FB1" TargetName="Circle"/>
<Setter Property="Stroke" Value="#222" TargetName="Arrow"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" Value="#FF526C7B" TargetName="Circle"/>
<Setter Property="StrokeThickness" Value="1.5" TargetName="Circle"/>
<Setter Property="Stroke" Value="#FF003366" TargetName="Arrow"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Here are the expand collapse events:
private void Expander_Expanded(object sender, RoutedEventArgs e)
{
for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
if (vis is DataGridRow)
{
var row = (DataGridRow)vis;
row.DetailsVisibility = row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
break;
}
}
private void Expander_Collapsed(object sender, RoutedEventArgs e)
{
for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
if (vis is DataGridRow)
{
var row = (DataGridRow)vis;
row.DetailsVisibility = row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
break;
}
}
The
ContentPresenter
in the defaultDataGridRowHeader
template has a hard-codedVericalAlignment
ofCenter
. You need to modify the template to be able to fix this:Don't fortget to add a reference to
PresentationFramework.Aero2.dll
.