Padding on a Datagrid Row - wpf

I have a WPF Datagrid with a Text Column, two Template Columns, and two Checkbox Columns.
The template columns are center aligned vertically (equal padding top and bottom), the text column has a little padding on top, but a lot on the bottom, and the checkboxes only have about 1 pixel padding on top.
I'd like to center vertical align all of them, but I don't want to have to make a template column to hold the check boxes and text box.
What's the proper way to do this?
Edit: XAML
<DataGrid AutoGenerateColumns="False" Name="dgROList" ItemsSource="{Binding ElementName=MainWindow, Path=cROInfo}" CanUserDeleteRows="True" CanUserReorderColumns="False" GridLinesVisibility="Horizontal" Margin="0,0,0,0" Grid.ColumnSpan="2" AlternatingRowBackground="#FFFFE776">
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Name="mnuDelete" Header="Delete" />
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Columns>
<DataGridTextColumn Header="RO Number" Width="Auto" Binding="{Binding RONum}" />
<DataGridTemplateColumn x:Name="roDetails" Header="RO Details" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ItemsControl Name="LineDetails" ItemsSource="{Binding LineInfo}" Width="Auto" Grid.IsSharedSizeScope="True">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ItemsPresenter />
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="Auto" SharedSizeGroup="DetailCol"/>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="150*"/>
</Grid.ColumnDefinitions>
<Label Content="{Binding Line}" Grid.Column="0" />
<Label Content="{Binding Status}" Grid.Column="1" />
<Label Content="{Binding AmountPaid}" Grid.Column="2" />
<Label Content="{Binding SDate}" Grid.Column="3" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn x:Name="roRI" Header="RI" Width="Auto" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding RI}" ToolTipService.ShowDuration="60000" ></Label>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridCheckBoxColumn Header="Paid" Width="40" Binding="{Binding Paid}" />
<DataGridCheckBoxColumn Header="Adj" Width="30" Binding="{Binding Adjustment}" />
</DataGrid.Columns>
</DataGrid>
Edit 2: Actually, I don't even need to vertically align them. Just adding a little padding to the top so it'll line up with the top of the Template Columns.

have you tried this:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>

Related

WPF DataTemplate and columns definition

I need to improve the render of my grid. I have a template:
<DataTemplate x:Key="ubitTemplateService" DataType="{x:Type data:uBit}">
<Grid HorizontalAlignment="Stretch" x:Name="grdBit">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="MAMC" />
<ColumnDefinition Width="Auto" SharedSizeGroup="ID" />
<ColumnDefinition Width="Auto" SharedSizeGroup="lblVIS" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding FIELD_Mac, Mode=OneWay}" Style="{StaticResource labelStyle1}" />
<TextBlock Grid.Column="1" Text="{Binding Name}" Style="{StaticResource txtBlockStyle2}" />
<Label Grid.Column="1" Content="{Binding Show.Caption}" Style="{StaticResource labelStyle4}" />
</Grid>
</DataTemplate>
Basically for each record of my collection, a grid is rendered but as I have 300 or more record, the whole render takes about 2-3 seconds (each template was rendered into a Listbox)
I would want to change the layout and use a datagrid as follows:
<DataGrid x:Name="gridDati" BorderBrush="#abadb3" CanUserSortColumns="true" Margin="8,7,5,8">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Name" CellTemplateSelector="{StaticResource DataTemplateSelector}" />
</DataGrid.Columns>
</DataGrid>
and I would want to use a datatemplate in order to render the columns, which may changes base on my datatype. The template selector is:
<local:DataconfigTemplateSelector ubitTemplateAv="{StaticResource ubitTemplateAv}" x:Key="DataTemplateSelector" />
The problem is that I want to put into my datatemplate the definition of DataGrid columns, for example a DataGridTextColumn:
<DataTemplate x:Key="ubitTemplateAv">
<StackPanel>
...
</StackPanel>
</DataTemplate>
How can I put into my datatemplate the columns definition like?
<DataGridTextColumn Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" Header="Nome" Foreground="Black" IsReadOnly="True" x:Name="colName">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="Padding" Value="4,7,4,6" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding SurName, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" Header="SurName" Foreground="Black" IsReadOnly="True" x:Name="colSurName">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="Padding" Value="4,7,4,6" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
the key is to use DataGridTemplateColumn instead of DataGridTextColumn.
Then you can do this:
<DataGridTemplateColumn
Width="80">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Foo}" Padding="4,7,4,6"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Adjust height/position of multiple listviews so that content is aligned

I'm designing an application where I need to position multiple ListViews in a way that the content is aligned like this (simplified):
What I have:
The outer layout is a Grid (black)
The ListView (grey) on the left has a small header
The ListViews (grey) on the right are generated in an ItemsControl and have a fairly large header (vertical text). Also, they are part of a UserControl with additional content above them (not shown here)
What I want:
The contents (red) of all ListViews should be aligned and start at the same height (blue line)
I DON'T want to set the headers (green) to have the same height, because that would waste much space due to the large height difference.
The only solution I can think of is to calculate the height of all elements above the ListViews and the height of the headers, and then change the height of the upper Grid row so that the contents start at the same height. But that seems rather tedious, error prone and clumsy to me.
Is there a more elegant solution, maybe involving SharedGroupSize or binding the height property?
XAML for the overall layout:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<local:SomeControl1 x:Name="generalSettingsControl" Grid.Column="0" Grid.Row="0" />
<ListView ItemsSource="{Binding FirstList}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name"
DisplayMemberBinding="{Binding CombinedName}" />
<GridViewColumn Header="ID"
DisplayMemberBinding="{Binding ID}" />
</GridView>
</ListView.View>
</ListView>
<ItemsControl Grid.Column="1" Grid.RowSpan="2" ItemsSource="{Binding Samples}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:ListViewUserControl DataContext="{Binding }" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
XAML for the ListViews in the ItemsControl :
<UserControl.Resources>
<Style x:Key="verticalGridViewColumnHeader" TargetType="GridViewColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding}" FontWeight="Bold" Width="60"
VerticalAlignment="Center" TextAlignment="Center" HorizontalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="270" />
</TextBlock.LayoutTransform>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Text="Placeholder (TODO)" Grid.Column="0" />
<ListView x:Name="lvMeasurementsEdit"
ItemsSource="{Binding Measurements}"
Grid.Column="0"
Grid.Row="2">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Value 1" DisplayMemberBinding="{Binding Value1}"
HeaderContainerStyle="{StaticResource verticalGridViewColumnHeader}" Width="Auto" />
<GridViewColumn Header="Value 2" DisplayMemberBinding="{Binding Value2}"
HeaderContainerStyle="{StaticResource verticalGridViewColumnHeader}" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
</Grid>

Unable to see vertical scroll bar in datagrid when placed inside grid in WPF

From last 2 day I am stuck in a small problem which I don't know why I was not able to solve it. I had did lots off goggling and implemented various suggestion provided by stack overflow to solve out the problem but finally I am getting tired off by unsuccessful implementation.
My problem is that I want a scroll able data grid which could be placed inside a Grid control or DockPanel(As I had tried with both). Below is code which I am using.
<Grid IsEnabled="{Binding IsCalcVarGridPartEnable}">
<Grid.Resources>
<BooleanToVisibilityConverter x:Key="boolToVisiblityConverter" />
<sys.converters:BoolToVisibleHiddenConvertor x:Key="boolToVisibleHiddenConvertor"/>
<FrameworkElement x:Key="ProxyElement"
DataContext="{Binding}"/>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Border Style="{StaticResource SeperatorStyle}" Grid.Row="0">
<TextBlock Style="{StaticResource BannerTextStyle}" Text="Calculation Variable" />
</Border>
<Border Style="{StaticResource SeperatorStyle}" Grid.Row="2">
<Button Content="Edit" HorizontalAlignment="Right" Margin="10,5" Command="{Binding EditCalcVarCmd}" />
</Border>
<ContentControl Visibility="Collapsed"
Content="{StaticResource ProxyElement}"/>
<DataGrid AutoGenerateColumns="False"
Name="dataGridCalcVar"
VerticalAlignment="Top"
HorizontalAlignment="Left"
IsReadOnly="True"
SelectionMode="Single"
SelectionUnit="FullRow"
ItemsSource="{Binding CalcVarCollection}"
SelectedItem="{Binding SelectedCalcVar}"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick" >
<i:InvokeCommandAction Command="{Binding CalcVarDoubleClickedCmd}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.ColumnHeaderStyle>
<StaticResourceExtension ResourceKey="DataGridColumnHeaderStyle" />
</DataGrid.ColumnHeaderStyle>
<DataGrid.CellStyle>
<StaticResourceExtension ResourceKey="DataGridCellStyle" />
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Type Description" MinWidth="150" MaxWidth="200" Binding="{Binding CalcTypName}" />
<DataGridTextColumn Header="Variable Description" MinWidth="150" MaxWidth="200" Binding="{Binding CalcVarName}" />
<DataGridTextColumn Header="Major Description" MinWidth="150" MaxWidth="200" Binding="{Binding MjAcctTypDesc}"
Visibility="{Binding DataContext.IsMjMiAcctTypVisible, Source={StaticResource ProxyElement},
Converter={StaticResource boolToVisibleHiddenConvertor}}" />
<DataGridTextColumn Header="Minor Description" MinWidth="150" MaxWidth="200" Binding="{Binding MiAcctTypDesc}"
Visibility="{Binding DataContext.IsMjMiAcctTypVisible, Source={StaticResource ProxyElement},
Converter={StaticResource boolToVisibleHiddenConvertor}}" />
<DataGridTextColumn Header="DNA Value" MinWidth="50" MaxWidth="200" Binding="{Binding CalcVarValueName}" />
<DataGridTextColumn Header="Critical Value" MinWidth="50" MaxWidth="200" Binding="{Binding CriticalValueName}" />
<DataGridTextColumn Header="Note" MinWidth="150" MaxWidth="200" Binding="{Binding Note}" />
</DataGrid.Columns>
</DataGrid>
<sysclient:PartStatusView Grid.RowSpan="5" Grid.ColumnSpan="7"
Style="{DynamicResource PartStatusViewDefaultStyle}" IsTabStop="False"/>
</Grid>
Important: I am able to get scroll bar only when I set max height of Datagrid control but I don't want to set max-height property of either row or datagrid control. I want that when I resize window or whatever space is available datagrid is set into that space and when we query the data then if data data is greater than available space then data grid brings vertical scroll bar.
Please help me!!!!!
I hope I am able to explain my problem. :-) :-)
Thanks,
From what I can see there are two attributes which can help you here
add Grid.Row="1" to your data grid
remove VerticalAlignment="Top" from the same which actually prevent it to take height from the container
eg
<DataGrid AutoGenerateColumns="False"
Name="dataGridCalcVar"
Grid.Row="1"
HorizontalAlignment="Left"
IsReadOnly="True"
SelectionMode="Single"
SelectionUnit="FullRow"
ItemsSource="{Binding CalcVarCollection}"
SelectedItem="{Binding SelectedCalcVar}"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
I am assuming that you want to place grid in the middle row which takes up the remaining space.

wpf ListBox looks like datagrid?

I have a listbox control in my app.
I want to change his style to being look like to Datagrid (borders, columns, row...).
I don't want to using stantard datagrid - because its control cannot binding itemtemplte.
I trying to do it:
<ListBox
ItemsSource="{Binding Items}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Name="listBox1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding Id}" Margin="5"/>
</Border>
<Border BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding Name}" Margin="5"/>
</Border>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But it not looking good - as following:
it what i want to achieve:
Using Grid.IsSharedSizeScope
result
i believe you want the columns to be re-sized based on your string length, so Grid.IsSharedSizeScope is your choice here
example xaml
<ListBox ItemsSource="{Binding Items}"
Grid.IsSharedSizeScope="True">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="name" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border BorderThickness="1"
BorderBrush="Black">
<TextBlock Text="{Binding Name}"
Margin="5" />
</Border>
<Border BorderThickness="1"
Grid.Column="1"
BorderBrush="Black">
<TextBlock Text="{Binding Id}"
Margin="5" />
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
if you move SharedSizeGroup to id like below
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition SharedSizeGroup="id" />
</Grid.ColumnDefinitions>
result
Using ListView with GridView
You have an option to use list view with grid view which will have same appearance as grid with flexibility of list
eg
<ListView ItemsSource="{Binding SourceItems}">
<ListView.View>
<GridView>
<GridViewColumn Header="Column1"
DisplayMemberBinding="{Binding Column1}" />
<GridViewColumn Header="Column2"
DisplayMemberBinding="{Binding Column2}" />
</GridView>
</ListView.View>
</ListView>
GridViewColumn offers you to modify CellTemplate, HeaderTemplate, HeaderContainerStyle, HeaderStringFormat etc.
I am sure you can achieve this using a grid control (It supports binding and everything else)
To fix your problem, you will have to give fixed widths to both your borders inside your stackpanel then your listbox items will look like a grid control.
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border Width="150" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding Id}" Margin="5"/>
</Border>
<Border Width="50" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding Name}" Margin="5"/>
</Border>
</StackPanel>
Please let us know what problem you are having with GridControl and maybe we can fix that as well
Edit. If you were using a DataGrid your template would look like
<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" HeadersVisibility="None">
<DataGrid.Columns>
<DataGridTemplateColumn Header="" Width="SizeToCells" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text={Binding Id}/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="" Width="SizeToCells" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text={Binding Name}/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Please note that I have set HeaderVisibility to false so that it doesnt look like a datagrid but instead looks like a list

Datagrid Column Header Templating

I want to template some headercolumns in a pretty simple way, but I don't get the results I am looking for. I want the Border to fill the whole header, not just the textbox inside. Right now I am still having the default gray behind my own controls.
<DataGrid x:Name="grdItems"
Grid.Row="0"
CanUserAddRows="False"
CanUserDeleteRows="False"
ItemsSource="{Binding Path=Items}"
CanUserSortColumns="False" AutoGenerateColumns="False" CanUserResizeColumns="False">
<DataGrid.Columns>
<DataGridComboBoxColumn ItemsSource="{Binding Source={StaticResource GetSignalTypeValues}}" Width="auto" SelectedValueBinding="{Binding SignalType}" >
<DataGridComboBoxColumn.HeaderTemplate>
<DataTemplate>
<Border Background="Orange" >
<TextBlock Text="Signal Type" />
</Border>
</DataTemplate>
</DataGridComboBoxColumn.HeaderTemplate>
</DataGridComboBoxColumn>
<DataGridTextColumn Width="auto" Binding="{Binding AmplitudeMax}">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<Border Background="Violet">
<StackPanel>
<TextBlock Text="Amplitude" HorizontalAlignment="Center" />
<TextBlock Text="-maximum-" HorizontalAlignment="Center" />
</StackPanel>
</Border>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
If you are only after background color of column header you can utilize this:
<DataGridComboBoxColumn Width="auto" SelectedValueBinding="{Binding SignalType}" >
<DataGridComboBoxColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="Background" Value="Orange"/>
</Style>
</DataGridComboBoxColumn.HeaderStyle>

Resources