Set TextWrapping to Wrap for all Cells, using template - c#

So, I`v got the next problem:
I am setting up a customized table (which is getting filled from the DB), where the content of the cells will be wraped.
I am able to set the view correctly. The code is:
<Grid Style="{StaticResource FormBackground}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15" />
<RowDefinition Height="*" />
<RowDefinition Height="40" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Grid Grid.Column="1" Grid.Row="1">
<Border Style="{StaticResource DGBorder}">
<DataGrid x:Name="usuariosGrid"
AutoGenerateColumns="False"
CanUserAddRows="False"
Grid.Row="0"
Style="{StaticResource Table}" >
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="40" Binding="{Binding Id}" IsReadOnly="True">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Nombre" Width="*" Binding="{Binding Nombre}" IsReadOnly="True">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Apellido Paterno" Width="*" Binding="{Binding ApellidoPaterno}" IsReadOnly="True">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Apellido Materno" Width="*" Binding="{Binding ApellidoMaterno}" IsReadOnly="True">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="CorreoElectronico" Width="*" Binding="{Binding CorreoElectronico}" IsReadOnly="True">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Border>
</Grid>
Works good, but is pretty much ugly, cause I have to set TextBox -> TextWrapping -> Wrap custom for every column. As well - the project contains multiple DataGrids. So for sure - I want to pack it all into a ResourceDictionary, which is:
<Style x:Key="Table" TargetType="DataGrid">
<Setter Property="Foreground" Value="{StaticResource WhiteBrush}" />
<Setter Property="RowBackground" Value="Transparent"/>
<Setter Property="AlternatingRowBackground" Value="{StaticResource DarkBlueFadedBrush}" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ColumnHeaderStyle" Value="{StaticResource DGColumnHeader}" />
<Setter Property="RowStyle" Value="{StaticResource SelectedRow}"/>
<Setter Property="GridLinesVisibility" Value="None" />
<Setter Property="RowHeaderWidth" Value="0" />
<Setter Property="BorderBrush" Value="{StaticResource LightBlueBrush}" />
</Style>
And at this point fun begins: DataGridTextColumn is not supported for setting it as style.
Well - where is a will, there is a way. Said one of the comrades around the web and gave a suggestion to use a back code. Which is fair. But I have a belief, that such type of improvements should be divided (and because it would be necessary to add back code to each one of the viewers, which contains forms).
Any suggestions, working directions, etc. would be appreciated.

This is what worked for me, in this particular situation.
Style:
<Style TargetType="{x:Type TextBlock}" x:Key="WrapText">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
Usage:
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="40" Binding="{Binding Id}" IsReadOnly="True" ElementStyle="{StaticResource WrapText}" />
So, the whole trick was about defining style with a ElementStyle property, when describing DataGridTextColumn. Hope it will be helpful.

If you want multiple things to remain common across all DataGrids. Derive a new class from DataGrid thus creating new Control.
And you can always do this : <DataGridTextColumn ElementStyle="{StaticResource tbKey}" Binding="{Binding Name}"/> .
<Style TargetType="TextBlock" x:Key="tbKey">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>

Related

Responsive Datagrid vertically when maximize the window

I'm trying to set the height of the rows in the datagrid dynamically , I mean the height of the datagrid should be based on the data binding ( from the database ) , I don't have a problem with columns , they are responsive when I maximize the window the columns increase and take the available space.
The problem now is with rows so what I need exactly is when I maximize the Window , the datagrid should take the available space vertically ( increase the font size of the headers and the data shown in the datagrid).
Is there any possibility to make the rows of the datagrid responsive ?
Xaml Code:
<DockPanel Grid.Row="2" Width="auto" MinWidth="800" Height="auto" >
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
<DataGrid VerticalScrollBarVisibility="Auto" Margin="20" Height="auto" Width="auto" GridLinesVisibility="All" ItemsSource="{Binding GridModel}" x:Name="UserGrid" MinWidth="1200"
VerticalAlignment="Top" FlowDirection="RightToLeft"
AutoGenerateColumns="False" CanUserAddRows="false" MinHeight="800"
Grid.RowSpan="2" RenderTransformOrigin="0.497,0.551" MouseDoubleClick="UserGrid_MouseDoubleClick" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Hidden">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Height" Value="Auto"/>
</Style>
</DataGrid.RowStyle>
<DataGrid.Resources>
<Style x:Key="DisableSelection" TargetType="DataGridCell">
<!-- <Setter Property="Focusable" Value="False"/> -->
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderBrush" Value="Transparent"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="choose" x:Name="choose" Binding="{Binding isChecked}" >
<DataGridCheckBoxColumn.CellStyle>
<Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEditing" Value="True"/>
</Trigger>
</Style.Triggers>
<EventSetter Event="CheckBox.Checked" Handler="OnChecked"/>
<EventSetter Event="CheckBox.Unchecked" Handler="OnChecked"/>
<Setter Property="Background" Value="Transparent" />
</Style>
</DataGridCheckBoxColumn.CellStyle>
</DataGridCheckBoxColumn>
<DataGridTextColumn Width="*" CellStyle="{StaticResource DisableSelection}" Header="IDw" x:Name="workIdcl" Binding="{Binding wId}" IsReadOnly="True" />
<DataGridTextColumn Width="*" CellStyle="{StaticResource DisableSelection}" Header="subName" x:Name="subscriberNamecl" Binding="{Binding subName}" IsReadOnly="True"/>
<DataGridTextColumn Width="*" CellStyle="{StaticResource DisableSelection}" Header="UserName" x:Name="patientNamecl" Binding="{Binding UserName}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</ScrollViewer>
</DockPanel>

How to wrap text while in edit mode on TextBlock WPF DataGridTextColumn

I have a DataGridTextColumn in which I wrap text in one column.Since only one cell has more than numbers and for this case cable names it' displaying fine in 3 lines, but while in edit mode the wrapping goes away and I don't see the whole text. Using the arrow keys is needed. I'd like to have an editable and textwrapping texblock while in edit mode. Looked for some advice on SO but no success.
Any help?
CableEditorWindow.xaml:
<Controls:MetroWindow x:Class="GPZmodel.Windows.CableEditorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Edytor właściwości kabla" Height="664" Width="610"
Background="WhiteSmoke" WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto" MinHeight="70"/>
</Grid.RowDefinitions>
<DataGrid x:Name="CableEditDataGrid"
Style="{StaticResource AzureDataGrid}"
Grid.Row="0"
VerticalAlignment="Stretch"
ItemsSource="{Binding Rows, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
CanUserAddRows="False"
CanUserDeleteRows="False" CanUserSortColumns="True" AutoGenerateColumns="False"
ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto"
SelectionMode="Single">
<DataGrid.Columns>
<DataGridTextColumn Header="Pole" Width="Auto"
HeaderStyle="{StaticResource WysrodkujHeader}"
Binding="{Binding nazwa_pola,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
IsReadOnly="True"
>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Text" Value="ID">
<Setter Property="Background" Value="#FF84BCCD"/>
<Setter Property="FontSize" Value="13"/>
</Trigger>
</Style.Triggers>
<Setter Property="TextAlignment" Value="Center"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<!--THIS-->
<DataGridTextColumn Header="Wartość"
HeaderStyle="{StaticResource WysrodkujHeader}"
Width="*"
Binding="{Binding wartosc_pola, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
>
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ReadOnly}" Value="True">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Focusable" Value="False"/>
</DataTrigger>
</Style.Triggers>
<Style.Setters>
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style.Setters>
</Style>
</DataGridTextColumn.CellStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextBlock.TextWrapping" Value="Wrap"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<!--/THIS-->
<DataGridTextColumn x:Name="JednostkaTextBox"
Header="Jednostka"
HeaderStyle="{StaticResource WysrodkujHeader}"
Binding="{Binding jednostka_pola,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
IsReadOnly="True"
Width="0.4*">
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<Grid Grid.Row="1" Background="#4A6A95">
<Button Style="{StaticResource MainButtonStyle}" Content="Nadpisz" x:Name="NadpiszButton" HorizontalAlignment="Right" Width="120" Panel.ZIndex="1" Margin="0,0,10,21" Height="32" VerticalAlignment="Bottom" Click="NadpiszButton_Click" />
<Button Style="{StaticResource MainButtonStyle}" Content="Anuluj" Name="AnulujButton" Height="32" VerticalAlignment="Bottom" Panel.ZIndex="1" Margin="0,0,135,21" HorizontalAlignment="Right" Width="120" Click="AnulujButton_Click" />
</Grid>
</Grid>
Besides the ElementStyle for the TextBlock, you should also define an EditingElementStyle that sets the TextWrapping property for the TextBox to Wrap:
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="TextBox">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</DataGridTextColumn.EditingElementStyle>
There is no TextBlock displayed while you're in edit mode. It's a TextBox.
Luckily, solution is simple:
add EditingElementStyle to your column, you can (or should) customize edit style separately
<DataGridTextColumn.EditingElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap"/>
</Style>
</DataGridTextColumn.EditingElementStyle>
Your final code portion will look like this
<!-- THIS -->
<DataGridTextColumn Width="*"
Binding="{Binding wartosc_pola, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Header="Wartość"
HeaderStyle="{StaticResource WysrodkujHeader}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ReadOnly}" Value="True">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Focusable" Value="False" />
</DataTrigger>
</Style.Triggers>
<Style.Setters>
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style.Setters>
</Style>
</DataGridTextColumn.CellStyle>
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.EditingElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
<!-- /THIS -->

C# WPF DataGridCheckboxColumn check one check many

I have some problem in using DataGridCheckBoxColumn. For some cell, when I check one checkbox, multiple checkboxes are checked at the same time. How should I prevent this? Here is my XAML.
<DataGrid IsReadOnly="True" Margin="10,0,10,8" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="2" Name="newsStories" AutoGenerateColumns="False" RowHeaderWidth="0">
<DataGrid.Columns>
<DataGridTextColumn Width="8*" Header="Headline" Binding="{Binding Path=heading}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
<Setter Property="TextBlock.Padding" Value="5" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridCheckBoxColumn Header="Select" Width="2*" Binding="{Binding Path=isIncluded, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}">
<DataGridCheckBoxColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</DataGridCheckBoxColumn.HeaderStyle>
<DataGridCheckBoxColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.HorizontalAlignment" Value="Center" />
<Setter Property="TextBlock.VerticalAlignment" Value="Center" />
</Style>
</DataGridCheckBoxColumn.ElementStyle>
<DataGridCheckBoxColumn.CellStyle>
<Style>
<EventSetter Event="CheckBox.Checked" Handler="handleChecked" />
<EventSetter Event="CheckBox.Unchecked" Handler="handleChecked" />
</Style>
</DataGridCheckBoxColumn.CellStyle>
</DataGridCheckBoxColumn>
</DataGrid.Columns>
</DataGrid>
I don't have any code-behind to show here. The problem is here even though I don't have any code-behind.
Thank you.

WPF Design Layout vs Compiled Layout

I'm getting differences between the design in VS2010 and the layout when compiled. See the images bellow:
Design View
Compiled
I have read this and I don't seem to be able to pick anything out that will help me. Why does this happen?
XAML:
<Window x:Class="iAdvert_Desktop.TemplateDesigner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="622" Width="610" AllowsTransparency="False" Opacity="1" Background="White" ResizeMode="NoResize">
<Window.Resources>
<ResourceDictionary Source="Pages/BaseStyle.xaml" />
</Window.Resources>
<Grid>
<Canvas Height="281" VirtualizingStackPanel.VirtualizationMode="Standard" HorizontalAlignment="Left" Name="canvas1" VerticalAlignment="Top" Width="500" Background="#FF383838" PreviewMouseLeftButtonDown="canvas1_PreviewMouseLeftButtonDown" PreviewMouseMove="canvas1_PreviewMouseMove" PreviewMouseLeftButtonUp="canvas1_PreviewMouseLeftButtonUp" Margin="45,30,0,0" Panel.ZIndex="5"></Canvas>
<DataGrid AutoGenerateColumns="False" CanUserAddRows="False" CanUserResizeColumns="False" CanUserResizeRows="False" DataContext="{Binding}" HeadersVisibility="Column" Height="143" HorizontalAlignment="Left" HorizontalContentAlignment="Stretch" HorizontalGridLinesBrush="#ccc" Margin="45,356,0,0" Name="dataGrid1" VerticalAlignment="Top" VerticalGridLinesBrush="#ccc" VirtualizingStackPanel.VirtualizationMode="Standard" Background="#FFF6F6F6" Width="500">
<DataGrid.Resources>
<ResourceDictionary Source="Pages/DataGridStyle.xaml" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Delete">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
<Image Source="/iAdvert-Desktop;component/Images/icons/delete.png" Height="12" MouseLeftButtonUp="Image_MouseLeftButtonUp"></Image>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="0.5*" Binding="{Binding Path=TemplateCellID}" Header="ID"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="1*" Binding="{Binding Path=CellWidth}" Header="Width"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="1*" Binding="{Binding Path=CellHeight}" Header="Height"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="1*" Binding="{Binding Path=CellTop}" Header="Top"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="1*" Binding="{Binding Path=CellLeft}" Header="Left"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<Button Content="Add Cell" Height="23" Name="button1" Width="75" Click="button1_Click" Margin="470,317,43,243" />
<TextBox Style="{StaticResource TextBoxStyle}" Height="26" HorizontalAlignment="Right" Margin="0,504,271,0" Name="textBox1" VerticalAlignment="Top" Width="178" />
<TextBlock Style="{StaticResource TextDescription}" Height="26" HorizontalAlignment="Left" Margin="45,504,0,0" Name="textBlock1" Text="Template Name" VerticalAlignment="Top" />
<Button Content="Save Template" Height="23" HorizontalAlignment="Left" Margin="450,505,0,0" Name="button2" VerticalAlignment="Top" Width="95" Click="button2_Click" />
</Grid>
</Window>
BaseStyle:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TextHeader" TargetType="TextBlock">
<Setter Property="Background" Value="#FF333333" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Padding" Value="5" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="16" />
</Style>
<Style x:Key="TextDescription" TargetType="TextBlock">
<Setter Property="Background" Value="#FF333333" />
<Setter Property="Padding" Value="5" />
<Setter Property="Foreground" Value="White" />
</Style>
<Style x:Key="ButtonStyle" TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF333333" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="5" />
</Trigger>
</Style.Triggers>
<Setter Property="Background" Value="#FF333333" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="#FF333333" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="5" />
</Style>
<Style x:Key="TextBoxStyle" TargetType="TextBox">
<Setter Property="BorderBrush" Value="#FF333333" />
<Setter Property="Height" Value="26" />
</Style>
</ResourceDictionary>
DataGridStyle:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type DataGrid}">
<Setter Property="ItemsControl.AlternationCount" Value="2" />
<Setter Property="BorderBrush" Value="#FF333333" />
</Style>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Control.Foreground" Value="White" />
<Setter Property="Control.Background" Value="#333" />
<Setter Property="Control.Padding" Value="5" />
</Style>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Control.Background" Value="#f1f1f1" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Control.Background" Value="#f9f9f9" />
</Trigger>
<Trigger Property="DataGridRow.IsSelected" Value="True">
<Setter Property="Control.Background" Value="#ccc" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<ContentPresenter VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FrameworkElement.Height" Value="20" />
</Style>
<Style x:Key="CenterCell" TargetType="{x:Type DataGridCell}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<ContentPresenter HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CenterTextCell" TargetType="{x:Type TextBlock}">
<Setter Property="TextAlignment" Value="Center" />
</Style>
</ResourceDictionary>
I think you'll find that this works better. It looks the same in the designer and when you run it.
All I have done is remove your margins and add rows/columns to your grid (and a stackpanel for the template label/textbox).
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="301"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Canvas Grid.Row="0" Background="#FF383838" ></Canvas>
<Button Grid.Row="1" Content="Add Cell" Height="23" Width="75" HorizontalAlignment="Right" Margin="0,10,0,10" />
<DataGrid Grid.Row="2" AutoGenerateColumns="False" DataContext="{Binding}" HeadersVisibility="Column"
HorizontalGridLinesBrush="#ccc" VerticalGridLinesBrush="#ccc" VirtualizingStackPanel.VirtualizationMode="Standard" Background="#FFF6F6F6" >
<DataGrid.Columns>
<DataGridTemplateColumn Header="Delete">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="0.5*" Binding="{Binding Path=TemplateCellID}" Header="ID"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="1*" Binding="{Binding Path=CellWidth}" Header="Width"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="1*" Binding="{Binding Path=CellHeight}" Header="Height"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="1*" Binding="{Binding Path=CellTop}" Header="Top"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource CenterTextCell}" Width="1*" Binding="{Binding Path=CellLeft}" Header="Left"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<Grid Grid.Row="3" Margin="0,10,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource TextDescription}" Height="26" Name="textBlock1" Text="Template Name" />
<TextBox Style="{StaticResource TextBoxStyle}" Height="26" Name="textBox1" Width="178" />
</StackPanel>
<Button Grid.Column="1" Content="Save Template" Height="23" Width="95" />
</Grid>
</Grid>
The simplistic answer to this is that the engine used to render the display in Visual Studio has a bug in it that impacts rendering of your application. You would need to post your XAML code for others to check but it may be worth opening your XAML in Expression Blend to see if the rendering is closer to what you see in the compiled version.

DataGrid row content vertical alignment

I have a regular DataGrid from WPF 4.0 RTM, where I put data from a database. In order to make clean & light style of DataGrid I use a tall/high rows and by default DataGrid aligns row content in top vertical position, but I want to set a center vertical alignment.
I already tried to use this property
VerticalAlignment="Center"
in DataGrid options, but it doesn't help me.
Here is an example of XAML-code, describing my DataGrid without center vertical alignment:
<DataGrid x:Name="ContentDataGrid"
Style="{StaticResource ContentDataGrid}"
ItemsSource="{Binding}"
RowEditEnding="ContentDataGrid_RowEditEnding">
<DataGrid.Columns>
<DataGridTextColumn Header="UserID"
Width="100"
IsReadOnly="True"
Binding="{Binding Path=userID}" />
<DataGridTextColumn Header="UserName"
Width="100"
Binding="{Binding Path=userName}" />
<DataGridTextColumn Header="UserAccessLevel"
Width="100"
Binding="{Binding Path=userAccessLevel}" />
<DataGridTextColumn Header="UserPassword"
Width="*"
Binding="{Binding Path=userPassword}" />
</DataGrid.Columns>
</DataGrid>
Result of executing this code:
As you can see all row content has top vertical align.
What do I have to add in order to get center vertical alignment of each row content?
Complete solution of this issue at MSDN: Vertical alignment of DataGrid row content.
In brief, in style-file set:
<!--body content datagrid cell vertical centering-->
<Style x:Key="Body_Content_DataGrid_Centering"
TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In window file:
<DataGrid x:Name="ContentDataGrid"
Style="{StaticResource ContentDataGrid}"
CellStyle="{StaticResource Body_Content_DataGrid_Centering}"
ItemsSource="{Binding}"
RowEditEnding="ContentDataGrid_RowEditEnding">
<DataGrid.Columns>
<DataGridTextColumn Header="UserID"
Width="100"
IsReadOnly="True"
Binding="{Binding Path=userID}" />
<DataGridTextColumn Header="UserName"
Width="100"
Binding="{Binding Path=userName}" />
<DataGridTextColumn Header="UserAccessLevel"
Width="100"
Binding="{Binding Path=userAccessLevel}" />
<DataGridTextColumn Header="UserPassword"
Width="*"
Binding="{Binding Path=userPassword}" />
</DataGrid.Columns>
</DataGrid>
This will give you a wanted result:
To set individual text alignments you can use:
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
The following code will vertically align the content of a DataGridTextColumn cell:
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
</Style>
</DataGridTextColumn.ElementStyle>
Edit: I've come back to this problem and found the solution below to work better, it will center the contents of all the cells in DataGridTextRows both horizontally and vertically.
<UserControl.Resources>
<ResourceDictionary>
<Style TargetType="DataGridCell">
<Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
<Setter Property="VerticalAlignment" Value="Stretch"></Setter>
<Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
<Setter Property="TextBlock.TextAlignment" Value="Center"></Setter>
<Setter Property="TextBlock.VerticalAlignment" Value="Center"></Setter>
</Style>
</ResourceDictionary>
</UserControl.Resources>
This one works for me
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.CellStyle>
You could also do without overriding the ControlTemplate:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
The attribute value VerticalAlignment="Center" will center the DataGrid within its parent element.
You probably want VerticalContentAlignment.
Just if someone might need it as i did..
To only affect a single column you could use the 'ElementStyle' Property:
<DataGrid ItemsSource="{Binding}">
<DataGrid.Resources>
<Style x:Key="DataGridVerticalText" TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Header Title" Binding="{Binding}" ElementStyle="{StaticResource DataGridVerticalText}" />
</DataGrid.Columns>
</DataGrid>
Building on Jamier's answer, the following code did the trick for me when using auto-generated columns:
Style VerticalCenterStyle = new Style();
public MainWindow()
{
// This call is required by the designer.
InitializeComponent();
VerticalCenterStyle.Setters.Add(new Setter(VerticalAlignmentProperty, VerticalAlignment.Center));
}
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.Column is DataGridTextColumn) {
((DataGridTextColumn)e.Column).ElementStyle = VerticalCenterStyle;
}
}
This is my simple solution and it just works perfectly
<DataGridTemplateColumn Header="Hello" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="World!" TextAlignment="Center" VerticalAlignment="Center"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I set the width to 200 so you can notice the difference.

Categories

Resources