question

EmonHaque-1485 avatar image
0 Votes"
EmonHaque-1485 asked EmonHaque-1485 commented

How to fix this auto column sizing issue in DataTemplate?

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-wpf
1.gif (2.6 MiB)
2.gif (512.7 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

EmonHaque-1485 avatar image
0 Votes"
EmonHaque-1485 answered EmonHaque-1485 commented

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


test.gif (880.7 KiB)
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@EmonHaque-1485
Putting TextBlock into Border also can aviod the issue, The reason may be that when drag the window Border can compute the position of its single child and applies its child's alignments to the child and determines its desired size it needs from the specified border the child: its sizing properties, margin, and requested size .

0 Votes 0 ·

@DaisyTian-MSFT, It doesn't work even if you put the TextBlock inside a Border.

0 Votes 0 ·

@EmonHaque-1485
it seems to be a rendering issue. I make move it to UWP app, and it works well as below:
106134-3.gif


0 Votes 0 ·
3.gif (2.6 MiB)
Show more comments