Styling GridView header with height and rotated text - wpf

I have created a gridview that displays as shown below:
What I would like to do is have the header height stretch as needed to fit the rotated text, how can I do this? Something like the below mockup (Note: obviously the rotated text won't be truncated)
Also as in the second mockup, I would like to have the rotated text a bit closer together. When you compare with the first image which seems to have the distance between each set by the width of the textblock. What is the best approach to get them closer?
Here is my XAML:
<UserControl.Resources>
<DataTemplate x:Key="headerTemplate">
<TextBlock HorizontalAlignment="Left" Text="{Binding}"/>
</DataTemplate>
<Style x:Key="GridHeaderStyle" TargetType="DataGridColumnHeader">
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
</Style>
<Style x:Key="ColumnHeaderStyle" TargetType="GridViewColumnHeader">
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
</Style>
<Style x:Key="rotatedText" TargetType="TextBlock">
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="-45" />
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<GridView>
<GridViewColumn Header="Name" HeaderTemplate="{StaticResource headerTemplate}" HeaderContainerStyle="{StaticResource ColumnHeaderStyle}" DisplayMemberBinding="{Binding Path=Name}"/>
<GridViewColumn Header="Job Title" HeaderTemplate="{StaticResource headerTemplate}" HeaderContainerStyle="{StaticResource ColumnHeaderStyle}" DisplayMemberBinding="{Binding Path=Job_Title}" />
<GridViewColumn Header="Department" HeaderTemplate="{StaticResource headerTemplate}" HeaderContainerStyle="{StaticResource ColumnHeaderStyle}" DisplayMemberBinding="{Binding Path=Department}" />
<GridViewColumn Header="Company" HeaderTemplate="{StaticResource headerTemplate}" HeaderContainerStyle="{StaticResource ColumnHeaderStyle}" DisplayMemberBinding="{Binding Path=Company}" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Company}">
<GridViewColumn.Header>
<StackPanel Orientation="Vertical">
<TextBlock HorizontalAlignment="Center">Modules</TextBlock>
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource rotatedText}" >Customer Services</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Asset Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Works Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Project Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Rates Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Finance</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Human Resources</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Document Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >User Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Configuration</TextBlock>
</StackPanel>
</StackPanel>
</GridViewColumn.Header>
</GridViewColumn>
</GridView>

Use LayoutTransform instead of RenderTransform. That will solve your problem.
<Style x:Key="rotatedText" TargetType="TextBlock">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-45" />
</Setter.Value>
</Setter>
</Style>

Related

WPF ListView Grouping and Repeat Header gridView

i have a listView and group descriptors to see my data (see capture1) .
I want to repeat Header Row of the grid on each "group" in the list view like capture2 below :
My xaml
<Grid Grid.Row="1" Margin="0,0,0,-80">
<ListView ItemsSource="{Binding ParcVoisinsCollectionView}" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" VerticalAlignment="Top" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView >
<!--<GridView.ColumnHeaderContainerStyle>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
<TextBlock Text="" Padding="5">
<TextBlock.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0.0" Color="#373638" />
<GradientStop Offset="1.0" Color="#77797B" />
</LinearGradientBrush>
</TextBlock.Background>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GridView.ColumnHeaderContainerStyle>-->
<GridViewColumn Header="NomParc" Width="50" DisplayMemberBinding="{Binding NomParc}" />
<GridViewColumn Header="NomEolienne" Width="120" DisplayMemberBinding="{Binding NomEolienne}" />
<GridViewColumn Header="TypeEolienne" Width="120" DisplayMemberBinding="{Binding TypeEolienne}" />
<GridViewColumn Header="Puissance" Width="50" DisplayMemberBinding="{Binding Puissance}" />
<GridViewColumn Header="Diametre" Width="120" DisplayMemberBinding="{Binding Diametre}" />
<GridViewColumn Header="Hauteur" Width="120" DisplayMemberBinding="{Binding Hauteur}" />
<GridViewColumn Header="X" Width="120" DisplayMemberBinding="{Binding PositionX}" />
<GridViewColumn Header="Y" Width="120" DisplayMemberBinding="{Binding PositionY}" />
</GridView>
</ListView.View>
<ListView.GroupStyle >
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />
<TextBlock Text="{Binding ItemCount}"
FontSize="22" Foreground="Green" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
<TextBlock Text=" éoliennes(s)" FontSize="22" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter>
</ItemsPresenter>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</Grid>
</Grid>
How can i make this ?

Styling rotated text in a stackpanel

The first image is when my program is run:
The second is from Visual Studio:
To get the rotated text closer together I have placed in the TextBlock style a margin of -50.
My question is how can I compensate for the margin on the first Textblock to stop it disappearing?
<UserControl.Resources>
<DataTemplate x:Key="headerTemplate">
<TextBlock HorizontalAlignment="Left" Text="{Binding}"/>
</DataTemplate>
<Style x:Key="GridHeaderStyle" TargetType="DataGridColumnHeader">
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
</Style>
<Style x:Key="ColumnHeaderStyle" TargetType="GridViewColumnHeader">
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
</Style>
<Style x:Key="rotatedText" TargetType="TextBlock">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-45" />
</Setter.Value>
</Setter>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Width" Value="130"/>
<Setter Property="Margin" Value="-50,0,0,0"/>
</Style>
</UserControl.Resources>
<GridView>
<GridViewColumn Header="Name" HeaderTemplate="{StaticResource headerTemplate}" HeaderContainerStyle="{StaticResource ColumnHeaderStyle}" DisplayMemberBinding="{Binding Path=Name}"/>
<GridViewColumn Header="Job Title" HeaderTemplate="{StaticResource headerTemplate}" HeaderContainerStyle="{StaticResource ColumnHeaderStyle}" DisplayMemberBinding="{Binding Path=Job_Title}" />
<GridViewColumn Header="Department" HeaderTemplate="{StaticResource headerTemplate}" HeaderContainerStyle="{StaticResource ColumnHeaderStyle}" DisplayMemberBinding="{Binding Path=Department}" />
<GridViewColumn Header="Company" HeaderTemplate="{StaticResource headerTemplate}" HeaderContainerStyle="{StaticResource ColumnHeaderStyle}" DisplayMemberBinding="{Binding Path=Company}" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Company}" HeaderContainerStyle="{StaticResource ColumnHeaderStyle}">
<GridViewColumn.Header>
<StackPanel Orientation="Vertical">
<TextBlock HorizontalAlignment="Center">Modules</TextBlock>
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource rotatedText}" >Customer Services</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Asset Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Works Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Project Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Rates Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Finance</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Human Resources</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Document Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >User Management</TextBlock>
<TextBlock Style="{StaticResource rotatedText}" >Configuration</TextBlock>
</StackPanel>
</StackPanel>
</GridViewColumn.Header>
</GridViewColumn>
</GridView>
Just give the first Module TextBlock a different Style having no negative margin.

Setting different alignments for listview columns

I'm having trouble drawing a listview with columns that are left or centre aligned. I've looked at a few of solutions that I've found on here or other forums but they either seem to work for all columns or I can't get them working.
The best I've got so far is this code, but everything is left aligned (I've put the right-aligns in to test the code). Can someone tell me where I'm going wrong please?
<ListView Name="lsvQuestions" DockPanel.Dock="Bottom">
<ListView.View>
<GridView>
<GridViewColumn Width="450" Header="Question Text">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding QuestionText}" TextAlignment="Left"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="200" Header="Type">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding QuestionType}" TextAlignment="Right"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="100" Header="Page Number">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding QuestionPageNumber}" TextAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="100" Header="Order">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding QuestionOrder}" TextAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Your ListViewItems don't stretch the content by default and that's why all items appear on the left. Add this and it will work:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
Although LPL's hint had already saved thousands of headaches, I would go even further and define HorizontalContentAlignment and VerticalContentAlignment to stretch in order to target an expected alignment behaviours on most used table driven controls:
ListView column headers and items templates
DataGrid column headers and cell templates.
<Window x:Class="TaskManager.UI.Views.AcumuladosPorTarefaWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:v="clr-namespace:TaskManager.UI.Views"
xmlns:catel="http://catel.codeplex.com"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="AcumuladosPorTarefaWindow" Height="451.533" Width="323.305"
>
<Window.Resources>
<Style TargetType="GridViewColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
<Style TargetType="DataGridCell">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
<ListView ItemsSource="{Binding AcumuladosPorTarefa}" SelectedItem="{Binding LinhaSelecionada}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding TarefaID}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
<GridViewColumnHeader>
<TextBlock Text="ID" TextAlignment="Center" />
</GridViewColumnHeader>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Tarefa.Nome}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
<TextBlock Text="Nome" TextAlignment="Left"/>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DuracaoInMS}" TextAlignment="Right" HorizontalAlignment="Stretch" />
</DataTemplate>
</GridViewColumn.CellTemplate>
<GridViewColumnHeader Width="auto">
<TextBlock Text="Duração" TextAlignment="Right"/>
</GridViewColumnHeader>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<DataGrid ItemsSource="{Binding AcumuladosPorTarefa}" AutoGenerateColumns="False" SelectedItem="{Binding LinhaSelecionada}" CanUserAddRows="False" HorizontalAlignment="Stretch">
<DataGrid.Columns>
<DataGridTemplateColumn Width="auto" MinWidth="20" CanUserSort="True" CanUserReorder="True" CanUserResize="True">
<DataGridTemplateColumn.Header>
<TextBlock Text="ID" TextAlignment="Right" />
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding TarefaID}" HorizontalAlignment="Stretch"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="auto" MinWidth="150" CanUserSort="True">
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="Nome" HorizontalAlignment="Left"/>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Tarefa.Nome}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Duração" Width="auto" MinWidth="25" IsReadOnly="True">
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="Duração" TextAlignment="Right"/>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DuracaoInMS}" TextAlignment="Right" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Window>
Rembember: you can always define your default styles and other resources at application level so you don't have to define it every view.
Hope it helps someone else like LPL's hint helped me.

How can I change the fontsize of a GridviewColumnHeader?

I included everything below since it's not that much. I wasn't sure if something I put elsewhere was causing my setter to not work properly.
<ListView x:Name="lvReports"
SelectionMode="Single"
ItemsSource="{Binding reportsCollection}" Height="432" ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<ListView.Resources>
<Style x:Key="myHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="TextElement.FontSize" Value="30pt"/>
<Setter Property="Width" Value="800"/>
</Style>
</ListView.Resources>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<DockPanel>
<DockPanel Height="30" VerticalAlignment="Bottom">
<Image Source="\Images\ProductivityByEmployeesReport.png"/>
<TextBlock FontWeight="Bold" FontSize="18pt" Text="{Binding Path=Name}"/>
</DockPanel>
</DockPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn x:Name="colName" HeaderContainerStyle="{StaticResource myHeaderStyle}" Header="Reports">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DockPanel>
<Rectangle Width="18"/>
<CheckBox>
<TextBlock Text="{Binding displayName}"/>
</CheckBox>
</DockPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Thanks in advance.
Add this to <ListView.Resources>
<Style TargetType="GridViewColumnHeader" x:Key="ColumnHeaderLarge">
<Setter Property="FontSize" Value="14"/>
</Style>
To set Fontsize to 14, use the style as:
<GridView ColumnHeaderContainerStyle="{StaticResource ColumnHeaderLarge}">

How do I group items in a WPF ListView

I have a ListView that I want to group results into, however the examples I am finding are not working. How can I group my results?
I want to group on the Status property of a custom object.
This is what I have:
<ListView IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Background="Transparent" SelectionChanged="ListView_SelectionChanged"
Name="lstShelvedOrders">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="15"
Text="{Binding Path=Status}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Width" Value="Auto" />
<Setter Property="FontSize" Value="10.4" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=Number}" Header="Shelve ID" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Customer}" Header="Customer" />
<GridViewColumn DisplayMemberBinding="{Binding Path=PurchaseOrderNo}" Header="PO Number" />
<GridViewColumn DisplayMemberBinding="{Binding Path=SubmittedBy}" Header="Shelved By" />
<GridViewColumn DisplayMemberBinding="{Binding Path=OrderDate, StringFormat=MMM dd\, yyyy}" Header="Date" />
<GridViewColumn DisplayMemberBinding="{Binding Path=CustomerTerms.Description}" Header="Order Terms" />
<GridViewColumn DisplayMemberBinding="{Binding Path=ShippingMethod.Description}" Header="Shipping" />
<GridViewColumn DisplayMemberBinding="{Binding Path=TotalPrice, StringFormat=c}" Header="Order Total" />
</GridView>
</ListView.View>
</ListView>
And this is the code that I have:
void ShelvedOrderList_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
AddGrouping();
}
private void AddGrouping()
{
if ( lstShelvedOrders.ItemsSource == null)
{
return;
}
CollectionView myView = (CollectionView)CollectionViewSource.GetDefaultView(lstShelvedOrders.ItemsSource);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("Status");
myView.GroupDescriptions.Add(groupDescription);
}
I notice one thing right away - the GroupStyle.HeaderTemplate will be applied to a CollectionViewGroup, so your DataTemplate should probably look like this:
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontSize="15" FontWeight="Bold" Text="{Binding Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
CollectionViewGroup.Name will be assigned the value of Status for that group.
I think this can also be better, using a GroupStyle with a new ControlTemplate:
<ListView ItemsSource="{Binding Path=ContactsView}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template" Value="{StaticResource ContactsGroupItemTemplate}" />
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
...
<ControlTemplate TargetType="{x:Type GroupItem}" x:Key="ContactsGroupItemTemplate">
<Expander IsExpanded="False">
<Expander.Header>
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100"/>
<TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}"/>
<TextBlock FontWeight="Bold" Text=" Items"/>
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>

Resources