I'm using a WPF4.0 DataGrid. When double clicking on a cell in a new row everything works fine unless I've added a cell style to that column. For example, I have a numeric column where I want the data right aligned so the xaml looks like this
<DataGridTextColumn Binding="{Binding Path=ImpaId}"
CellStyle="{StaticResource CellRightAlign}">
<DataGridTextColumn.Header>
<TextBlock Style="{StaticResource DataGridHeader}">Impa</TextBlock>
</DataGridTextColumn.Header>
</DataGridTextColumn>
Where the style in a shared resource is just:
<Style x:Key="CellRightAlign">
<Setter Property="Control.HorizontalAlignment"
Value="Right" />
</Style>
The resulting selectable area on a new row is shown in the image as that small blue area.This is a very small target for the user to hit, and this happens to be the most likely column they will want to start with on a new row.
If I remove the CellStyle, the area works as desired but of course I lose the right alignment.
Does anyone know how to achieve both?
Things I tried
Thing that worked:
Using the information from the answer by @AngelWPF I was able to change from using CellStyle to using ElementStyle as follows:
<DataGridTextColumn Binding="{Binding Path=ImpaId}"
CellStyle="{StaticResource CellRightAlign}">
Became
<DataGridTextColumn Binding="{Binding Path=ImpaId}"
ElementStyle="{StaticResource CellRightAlign}">
You could apply ElementStyle
on the DataGridTextColumn
targetted to TextBlock
and right align that, it would work.
<DataGridTextColumn Binding="{Binding Path=ImpaId}">
<DataGridTextColumn.Header>
<TextBlock Style="{StaticResource
DataGridHeader}">
Impa
</TextBlock>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
Just wanted to add to more examples for future code searches.
I put this in the top of the xaml file:
<UserControl.Resources>
<Style TargetType="{x:Type TextBlock}" x:Key="RightCell">
<Setter Property="Background" Value="{Binding Included, Converter={StaticResource BoolToColorConverter}}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="TextAlignment" Value="Right"/>
</Style>
</UserControl.Resources>
And then in the datagrid:
<DataGridTextColumn Header="Excluded" Binding="{Binding Excluded}" ElementStyle="{StaticResource RightCell}"/>
This right aligns the text and sorting is still enabled. The textbox fills the cell and in this case is colored using a bool converter.
You can try a work around :
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid Background="White" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock HorizontalAlignment="Right" Text="{Binding Path=ImpaId}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I just had a similar problem and found another solution by overwriting the Style for the DataGridCell in Blend.
The changed items from the original style are the setters for VerticalAlignment
and VerticalContentAlignment
in the Style itself to stretch the cell itself and VerticalAlignment="Center"
and HorizontalAlignment="Right"
in the Template property to align the content. Change these values to whatever you need to align the cells content.
The rest of the style could be removed so that the settings from the base style will be used (using the StaticResource the style is BasedOn). However I left the style as Blend produced it.
This resulting XAML-Code should then be included into the controls resources:
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource ResourceKey={x:Type DataGridCell}}">
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<!-- Additional styles, can be removed to fall back to base styles -->
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource {ComponentResourceKey ResourceId=FocusBorderBrushKey, TypeInTargetAssembly={x:Type DataGrid}}}"/>
</Trigger>
</Style.Triggers>
</Style>
I had the same issue and got it solved now. If you want to do it inside the c# code, you need to set a bunch of setters:
DataGridTextColumn numColumn = new DataGridTextColumn
Style s = new Style();
s.Setters.Add(new Setter(HorizontalAlignmentProperty, HorizontalAlignment.Stretch));
s.Setters.Add(new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Right));
s.Setters.Add(new Setter(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Stretch));
s.Setters.Add(new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Right));
numColumn.CellStyle = s;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With