How to autosize and right-align GridViewColumn data in WPF?
Solution 1
To make each of the columns autosize you can set Width="Auto" on the GridViewColumn.
To right-align the text in the ID column you can create a cell template using a TextBlock and set the TextAlignment. Then set the ListViewItem.HorizontalContentAlignment (using a style with a setter on the ListViewItem) to make the cell template fill the entire GridViewCell.
Maybe there is a simpler solution, but this should work.
Note: the solution requires both HorizontalContentAlignment=Stretch in Window.Resources and TextAlignment=Right in the CellTemplate.
<Window x:Class="WpfApplication6.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</Window.Resources>
<Grid>
<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" Width="40">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Id}" TextAlignment="Right" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Solution 2
If the width of the contents changes, you'll have to use this bit of code to update each column:
private void ResizeGridViewColumn(GridViewColumn column)
{
if (double.IsNaN(column.Width))
{
column.Width = column.ActualWidth;
}
column.Width = double.NaN;
}
You'd have to fire it each time the data for that column updates.
Solution 3
If your listview is also re-sizing then you can use a behavior pattern to re-size the columns to fit the full ListView width. Almost the same as you using grid.column definitions
<ListView HorizontalAlignment="Stretch"
Behaviours:GridViewColumnResize.Enabled="True">
<ListViewItem></ListViewItem>
<ListView.View>
<GridView>
<GridViewColumn Header="Column *"
Behaviours:GridViewColumnResize.Width="*" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox HorizontalAlignment="Stretch" Text="Example1" />
</DataTemplate>
</GridViewColumn.CellTemplate>
See the following link for some examples and link to source code http://lazycowprojects.tumblr.com/post/7063214400/wpf-c-listview-column-width-auto
Solution 4
I have created the following class and used across the application wherever required in place of GridView
:
/// <summary>
/// Represents a view mode that displays data items in columns for a System.Windows.Controls.ListView control with auto sized columns based on the column content
/// </summary>
public class AutoSizedGridView : GridView
{
protected override void PrepareItem(ListViewItem item)
{
foreach (GridViewColumn column in Columns)
{
// Setting NaN for the column width automatically determines the required
// width enough to hold the content completely.
// If the width is NaN, first set it to ActualWidth temporarily.
if (double.IsNaN(column.Width))
column.Width = column.ActualWidth;
// Finally, set the column with to NaN. This raises the property change
// event and re computes the width.
column.Width = double.NaN;
}
base.PrepareItem(item);
}
}
Solution 5
Since I had an ItemContainerStyle I had to put the HorizontalContentAlignment in the ItemContainerStyle
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=FieldDef.DispDetail, Mode=OneWay}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
....
Angry Dan
web/software developer, .NET, C#, WPF, PHP, software trainer, English teacher, have philosophy degree, love languages, run marathons my tweets: http://www.twitter.com/edward_tanguay my runs: http://www.tanguay.info/run my code: http://www.tanguay.info/web my publications: PHP 5.3 training video (8 hours, video2brain) my projects: http://www.tanguay.info
Updated on July 08, 2022Comments
-
Angry Dan almost 2 years
How can I:
- right-align the text in the ID column
- make each of the columns auto size according to the text length of the cell with the longest visible data?
Here is the code:
<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}"> <ListView.View> <GridView> <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}" Width="40"/> <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="100" /> <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}"/> </GridView> </ListView.View> </ListView>
partial answer:
Thanks Kjetil, the GridViewColumn.CellTemplate works well and the Auto Width works of course but when the ObservativeCollection "Collection" is updated with longer-than-column-width data, the column sizes do not update themselves so that is only a solution for the initial display of data:
<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}"> <ListView.View> <GridView> <GridViewColumn Header="ID" Width="Auto"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Id}" TextAlignment="Right" Width="40"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" /> <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/> </GridView> </ListView.View> </ListView>
-
Gishu about 14 years@Kjetil - Can I apply this setting to a specific column ?
-
Armentage over 13 yearsWhat would you attach this to?
-
RandomEngy over 13 yearsRun it manually on the GridViewColumn after you've updated the grid data. If you've got a ViewModel you could subscribe to the PropertyChanged event on it and run it then.
-
gehho over 13 years+1 Thanks for that! This helped me a lot! Not related to this question, but anyway: I implemented a customized List/GridView where you can dynamically add/remove columns at runtime via the GUI. However, when I removed and re-added a column, it no longer appeared. First, I thought it was not added at all (for some reason), but then (using Snoop) I found out that it is actually added, but has an ActualWidth of 0 (it was auto-sized and obviously reset when the column was removed). Now, I use your code to set the column to the correct width after I re-added it to the Columns. Many thanks!
-
Helge Klein over 13 years+1 for: <Setter Property="HorizontalContentAlignment" Value="Stretch" />
-
Designpattern over 12 yearsThis one is cool. Solves the problem and gives you all the , n, Auto functionality you are looking for.
-
Jake Berger over 12 yearsTHIS is what I was looking for. :D
-
Jake Berger over 12 yearsNote: there seems to be a bug. When the ListView is resized vertically, to the point that causes a vertical scrollbar to appear, the column will continuously increase in width until the scrollbar disappears.
-
Jake Berger over 12 yearsThis post may provide insight on the behavior described in my previous comment.
-
Gqqnbig almost 12 yearsIt's cool, I mean both the code and the site:). I believe it will be useful when I have stricter requirements.
-
Gqqnbig almost 12 yearsA simple solution to my problem!
-
Nitin Chaudhari over 11 yearsawesome, but I have 15 columns, is there any way I dont have to repeat the celltemplate for all of them?
-
floele about 11 yearsIt also doesn't work if you forget to remove the DisplayMemberBinding from the GridViewColumn. The template won't have any effect then.
-
K0D4 about 11 years+1 Perfect! Wish this was marked as the answer. I added x:Name="gvcMyColumnName" to the XAML where the column was defined so I could access it in the code behind. Works like a champ.
-
It'sNotALie. over 10 years@Mohamed Why isn't it?
-
B.K. about 10 yearsYou have width of
GridViewColumn
as40
and you set column definition width toAuto
? That doesn't make sense. -
Boumbles about 8 yearsDoes anybody have a link to the source code? It was hosted on Google code and exporting it to Github doesn't show any more source.
-
Rolf Wessels about 8 yearsHmm, I see what you mean. I will go and check at home to see if I still have a backup somewhere.
-
Chris about 8 yearsSeems to only resize based on visible data (so, the first X rows), not necessarily the longest value for each column. Still nice though.
-
David almost 8 yearsWidth="Auto" seems to have no effect
-
J. Andersen about 6 yearsThis inspired me to this solution to fill the width of one column: <GridViewColumn Width="{Binding RelativeSource={RelativeSource AncestorType=ListView}, Path=ActualWidth}" >