How to fix this auto column sizing issue in DataTemplate?

Emon Haque 3,176 Reputation points
2021-06-13T13:48:05.843+00:00

Here's what it does in my app:

105096-1.gif

all columns, except Particulars are fixed width: 80. So when the Text is Wrapped the Particulars column, most of the time, takes up more space than necessary and the other columns right to it don't get required space! It gets fixed automatically when I scroll! Since I'm using HiBlock instead of normal TextBlock, I thought that the HiBlock is causing the issue BUT it isn't. Here's an example with TextBlock:

105162-2.gif

In the MainWindow.xaml, I've these:

<Grid Margin="20">  
    <Grid.RowDefinitions>  
        <RowDefinition Height="Auto"/>  
        <RowDefinition />  
    </Grid.RowDefinitions>  
    <Grid Margin="5 0 20 0">  
        <Grid.Resources>  
            <Style TargetType="TextBlock">  
                <Setter Property="FontWeight" Value="Bold"/>  
            </Style>  
        </Grid.Resources>  
        <Grid.ColumnDefinitions>  
            <ColumnDefinition Width="80"/>  
            <ColumnDefinition />  
            <ColumnDefinition Width="80"/>  
            <ColumnDefinition Width="80"/>  
            <ColumnDefinition Width="80"/>  
        </Grid.ColumnDefinitions>  
        <TextBlock Text="Date"/>  
        <TextBlock Grid.Column="1" Text="Particulars"/>  
        <TextBlock Grid.Column="2" Text="Debit" HorizontalAlignment="Right"/>  
        <TextBlock Grid.Column="3" Text="Credit" HorizontalAlignment="Right"/>  
        <TextBlock Grid.Column="4" Text="Balance" HorizontalAlignment="Right"/>  
    </Grid>  
    <ListBox Grid.Row="1"   
             ItemsSource="{Binding Entries}"  
             HorizontalContentAlignment="Stretch"  
             ScrollViewer.HorizontalScrollBarVisibility="Disabled">  
        <ListBox.ItemTemplate>  
            <DataTemplate>  
                <Grid>  
                    <Grid.ColumnDefinitions>  
                        <ColumnDefinition Width="80"/>  
                        <ColumnDefinition />  
                        <ColumnDefinition Width="80"/>  
                        <ColumnDefinition Width="80"/>  
                        <ColumnDefinition Width="80"/>  
                    </Grid.ColumnDefinitions>  
                    <TextBlock Text="{Binding Date, StringFormat='dd MMMM yyyy'}"/>  
                    <TextBlock Grid.Column="1" Text="{Binding Particulars}" TextWrapping="Wrap" Background="AntiqueWhite"/>  
                    <TextBlock Grid.Column="2" Text="{Binding Debit, StringFormat='N0'}" HorizontalAlignment="Right"/>  
                    <TextBlock Grid.Column="3" Text="{Binding Credit, StringFormat='N0'}" HorizontalAlignment="Right"/>  
                    <TextBlock Grid.Column="4" Text="{Binding Balance, StringFormat='N0'}" HorizontalAlignment="Right"/>  
                </Grid>  
            </DataTemplate>  
        </ListBox.ItemTemplate>  
    </ListBox>  
</Grid>  

and in MainWindow.xaml.cs these:

public partial class MainWindow : Window  
{  
    public List<Entry> Entries { get; set; }  
    public MainWindow() {  
        InitializeComponent();  
        var ipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque in nibh fringilla, cursus erat id, lacinia diam. Nam euismod ex placerat, aliquet nibh id, aliquam nulla. Curabitur sit amet sapien sed libero semper congue. Donec semper elit quis dui tempor laoreet. Duis lorem velit, viverra et pellentesque eget, sollicitudin eget orci. Nulla molestie risus eget suscipit pharetra. Nunc posuere, elit non rutrum sollicitudin, ante nibh commodo turpis, molestie semper odio quam luctus tellus. Maecenas imperdiet sodales ante, vel facilisis justo mollis nec. Praesent dictum dictum nisl, eu imperdiet eros pulvinar vitae.";  
        Random rand = new();  
        Entries = new();  
        for (int i = 0; i < 100; i++) {  
            Entries.Add(new Entry() {  
                Date = DateTime.Today,  
                Particulars = ipsum.Substring(0, rand.Next(0, ipsum.Length)),  
                Debit = rand.Next(5000, 500000),  
                Credit = rand.Next(5000, 500000),  
                Balance = rand.Next(5000, 500000)  
            });   
        }  
        DataContext = this;  
    }  
}  

public class Entry  
{  
    public DateTime Date { get; set; }  
    public string Particulars { get; set; }  
    public int Debit { get; set; }  
    public int Credit { get; set; }  
    public int Balance { get; set; }  
}  

How do you solve this issue?

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,783 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Emon Haque 3,176 Reputation points
    2021-06-13T16:12:46.79+00:00

    Found a weird trick like this:

    <DataTemplate>  
        <Grid>  
            <Grid.ColumnDefinitions>  
                <ColumnDefinition Width="80"/>  
                <ColumnDefinition />  
                <ColumnDefinition Width="80"/>  
                <ColumnDefinition Width="80"/>  
                <ColumnDefinition Width="80"/>  
            </Grid.ColumnDefinitions>  
            <TextBlock Text="{Binding Date, StringFormat='dd MMMM yyyy'}"/>  
            <Border x:Name="x" Grid.Column="1"/>  
            <TextBlock Grid.Column="1"   
                        Text="{Binding Particulars}"   
                        TextWrapping="Wrap"   
                        Background="AntiqueWhite"   
                        Width="{Binding ActualWidth, ElementName=x}"/>  
            <TextBlock Grid.Column="2" Text="{Binding Debit, StringFormat='N0'}" HorizontalAlignment="Right"/>  
            <TextBlock Grid.Column="3" Text="{Binding Credit, StringFormat='N0'}" HorizontalAlignment="Right"/>  
            <TextBlock Grid.Column="4" Text="{Binding Balance, StringFormat='N0'}" HorizontalAlignment="Right"/>  
        </Grid>  
    </DataTemplate>  
    

    where the Width of the TextBlock is bound to the ActualWidth of Border BUT it also fails at some point:

    105097-test.gif


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.