Wpf datagrid column header as Grid - wpf

I have DataGrid with customized column like that
<DataGridTemplateColumn Width="2*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding SomeProperty}"/>
<TextBlock Grid.Column="0" Text="{Binding OtherProperty}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Width="*" Header="Const" Binding="{Binding ConstantValue}" />
As you can see, first column has double width of second column and contains two texblocks. So I need make header consists from two words. Every word above corresponding TexBlock. And I try to use Grid with two columns (because I have textblocks in two columns) as HeaderTemplate. I try to set HeaderStyle like that
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Style.Setters>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Center">Header1</TextBlock>
<TextBlock Grid.Column="1" HorizontalAlignment="Center">Header2</TextBlock>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
and I try to use HeaderTemplate like that
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Center">Header1</TextBlock>
<TextBlock Grid.Column="1" HorizontalAlignment="Center">Header2</TextBlock>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
But in both cases I have the same wrong result. Namely. Header1 and Header2 placed togeter without any spaces like Header1Header2. And looks like Header1Header2 has HorizontalAligment="Left" relatively whole header.
I.e.
column border-->|Header1Header2___________|<--column border
So Header1 and Header2 do not placed above corresponding TextBlocks in DataGrid.
How can I solve my problem? How should I set HeaderTemplate to take what I want?

Would customizing the ControlTemplate work for you?
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Center">Header1</TextBlock>
<TextBlock Grid.Column="1" HorizontalAlignment="Center">Header2</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</DataGridTemplateColumn.HeaderStyle>
Your other option is to create your own DataGridColumnHeadersPresenter which will hint the available size to the headers. By default, headers' ContentPresenters won't be told the available size and will calculate the width from their content (DataTemplate).
In your case, the width is not set explicitly (e.g. <Grid Width="200">) so it'll simply be the combined size of the TextBoxes.

Related

Star sizing Grid columns in an ItemsControl?

I have a ListBox with an ItemsControl bound to a collection in my view model. I'm trying to use star sizing on a grid column within the DataTemplate and set the element within that column (a progress bar) to stretch. This normally would take up all available horizontal space in the grid however nested in an ItemsControl this does not seem to be the case. I've done a bit of reading around & there seems to be known issues using these controls together. Is there a solution to this?
<ListBox>
<ItemsControl ItemsSource="{Binding WebMappingSourcesCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid
ShowGridLines="True"
Grid.IsSharedSizeScope="true"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0"
HorizontalAlignment="Center" />
<TextBlock
Grid.Column="1"
Text="{Binding Name}"/>
<ProgressBar Grid.Column="2"
Minimum="0"
Maximum="100"
Value="30"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
MaxHeight="15"
/>
<!-- etc. etc. -->
Try setting HorizontalContentAlignment on your listbox item by giving ItemContainerStyle like below.
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

How can a ListBox fill its parent width?

I have a ListBox and need that it fills the parent's width but have not found a way to do it, the ListBox has always the ListBox width and not the 100%.
Here is my XAML code:
<ListBox ItemsSource="{Binding anagSearchResults}" BorderThickness="0" Background="Gray"
SelectedItem="{Binding selectCustomer}"
FontSize="14"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding FirstName}"></TextBlock>
....
What am I doing wrong?
I would check the HorizontalAlignment of the parent(s) and make sure none of them are set to left, right or centre.
I would go with a ListView GridView.
Then for width you need to use a converter.
Change the converter in this sample to be parent width / 4
enter link description here
See the checked answer from me

Grid doesn't stretch inside ListPicker item

I have Grid inside ListPicker full mode item. Grid has two columns. First column should be left-aligned and second right-aligned.
Unfortunately this template doesn't work as expected:
<DataTemplate x:Name="ListFullModeItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Name}" />
<TextBlock Grid.Column="1" Text="{Binding Description}" HorizontalAlignment="Right" />
</Grid>
</DataTemplate>
Second TextBlock doesn't align to right.
When I set Grid Width property to specific value i.e.
<Grid Width="700">
...
</Grid>
then it works, but I can't do it because user can rotate phone to Portrait/Landscape.
Any ideas?
EDIT:
I also had the same problem in ListBox.
I fixed it by adding:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
I can't use this in ListPicker because it doesn't have ItemContainerStyle element.
set your grid 's width.
and change it by +=:
OrientationChanged += new EventHandler(SecondPage_OrientationChanged);
try adding TextAlignment="Right"

Items in ListBox don't stretch properly

Check this xaml:
<Window
x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Width="300">
<ListBox HorizontalContentAlignment="Stretch"
Grid.IsSharedSizeScope="True">
<ListBox.ItemsSource>
<x:Array Type="{x:Type sys:Int32}">
<sys:Int32>25</sys:Int32>
<sys:Int32>10</sys:Int32>
<sys:Int32>50</sys:Int32>
<sys:Int32>30</sys:Int32>
<sys:Int32>80</sys:Int32>
</x:Array>
</ListBox.ItemsSource>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem"
BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="#FFE41515">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="name" Width="Auto"/>
<ColumnDefinition SharedSizeGroup="value"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Value:"/>
<ProgressBar
Value="{Binding Mode=OneWay}"
Grid.Column="1"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
Here's the output, notice that the ProgressBar isn't stretched, why?
If the items are red, it means that each item fills the entire width, then why isn't the ProgressBar stretching??
If you have only SharedSizeGroups the rest space will never be taken, they always behave like Width="Auto" (size to content) with the restriction of the largest item. As you only have two columns you do not even need two such groups as the second will already be the same width in every item, right?
How about this instead:
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="name" Width="Auto"/>
<ColumnDefinition /> <!-- Implicit: Width="*" -->
</Grid.ColumnDefinitions>

Lock a grid column in place when changing GridViewColumn width

I have a DataTemplate for a gridview column, it has 2 items in it, an image and a text block, I want to "lock" the image to the left side of the column, even if the user expand the width of the column, I want the image to stay put.
any ideas ?
Try to set HorizontalContentAlignment to Stretch for GridViewColumnHeader
<ListView ...>
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.Resources>
<!--...-->
</ListView>
Then your HeaderTemplate can look something like this if you want the TextBlock to be centered. Otherwise just remove the HorizontalAlignment
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" .../>
<TextBlock Grid.Column="1" HorizontalAlignment="Center" .../>
</Grid>
</DataTemplate>

Resources