0

I am trying to figure out why my last column in my datagrid created in WPF is not resizing appropriately after a record is added. Instead, only one of the buttons in the template column are partially visible. As the column is set to auto width, I would expect this to resize the first column (the star column) to fit the contents of the last column in the window.

Can someone please tell me where I'm going wrong here? As a side note, if I resize the window (not the column) afterwards, the column now shows all of the template column contents.

If this is just the way WPF works, is there a way to get the columns to recalculate to the auto/star values that are set after the first row is added?

This is a recreation of the issue in a simplified example so no, of course this is not my actual code and I would not normally code this in a code behind.

Code behind:

  public partial class MainWindow : Window
    {
        ObservableCollection<Test> TestCollection;
        public ICollectionView GridView { get; set;}
        public MainWindow()
        {
            
            InitializeComponent();
            this.DataContext = this;
            TestCollection = new ObservableCollection<Test>();
            GridView = CollectionViewSource.GetDefaultView(TestCollection);
      
        }

        private void TestButton_Click(object sender, RoutedEventArgs e)
        {
            TestCollection.Add(new Test { Field1 = "Test", Field2 = "Test", Field3 = "Test", Field4 = "Test" });
            GridView.Refresh();
        }
    }

    public class Test
    {
        public string Field1 { get; set; }
        public string Field2 { get; set; }
        public string Field3 { get; set; }
        public string Field4 { get; set; }
    }
}

XAML:

<Window x:Class="WpfApp4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp4"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="400">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" x:Name="TestButton" Click="TestButton_Click"/>
        <DataGrid Grid.Row="1" ItemsSource="{Binding GridView}" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Field1" Width="*" Binding="{Binding Field1}"/>
                <DataGridTextColumn Header="Field2" Width="Auto" Binding="{Binding Field1}"/>
                <DataGridTextColumn Header="Field3" Width="Auto" Binding="{Binding Field1}"/>
                <DataGridTextColumn Header="Field4" Width="Auto" Binding="{Binding Field1}"/>
                <DataGridTemplateColumn Header="Options">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>

                                </Grid.ColumnDefinitions>
                                <Button Grid.Column="0" Content="Test Button"/>
                                <Button Grid.Column="1" Content="Test Button 2"/>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>

                                </Grid.ColumnDefinitions>
                                <Button Grid.Column="0" Content="Test Button"/>
                                <Button Grid.Column="1" Content="Test Button 2"/>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>




            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Before insert

After insert

qscott86
  • 303
  • 3
  • 11
  • https://stackoverflow.com/questions/560581/how-to-autosize-and-right-align-gridviewcolumn-data-in-wpf/1931423#1931423 – RandomEngy Jul 05 '20 at 04:30
  • 1
    You're not doing anything wrong, it's just that the column is empty so the Auto width goes by the width of the column header. You can add in code behind of this view: [NameOfYourDataGrid].Columns[4].Width=CurrentWidthJustFixed; [NameOfYourDataGrid].Columns[4].Width=GridLength.Auto; After collection changed. – o_w Jul 05 '20 at 07:55
  • set width to * like this : `Width="*"` – NEBEZ Jul 05 '20 at 08:12

2 Answers2

0

Not sure of the root cause of problem, however setting the width of column again to auto in button click event solved the problem.I gave datagrid control the name 'dataGrid'

private void TestButton_Click(object sender, RoutedEventArgs e)
{
    TestCollection.Add(new Test { Field1 = "Test", Field2 = "Test", Field3 = "Test", Field4 = "Test" });
    GridView.Refresh();
    dataGrid.Columns[4].Width = new DataGridLength(1,DataGridLengthUnitType.Auto);
}
Durga Prasad
  • 939
  • 10
  • 20
  • 1
    Hmm - this didn't work for me... not sure why. I did find a solution though. – qscott86 Jul 05 '20 at 14:28
  • Oh I see, no problem. Glad that you were able to find the solution. If possible can you post the solution over here so that it can help someone who might run into a similar problem in future :) – Durga Prasad Jul 05 '20 at 14:37
  • 1
    I posted a few solutions I found below in a separate answer. – qscott86 Jul 06 '20 at 15:02
0

I was able to find a few ways to address this issue:

1.Setting CanUserAddRows in the Loaded event of the DataGrid as opposed to setting it in the XAML

private void Grid1_Loaded(object sender, RoutedEventArgs e)
{
            Grid1.CanUserAddRows = false;
}

Note: For this to work, InitializeComponent() must be called AFTER the collection is initialized

  1. Looping through all columns with Star as width and setting the width to the actual width and then back.

    private void TestButton_Click(object sender, RoutedEventArgs e)
    {
        TestCollection.Add(new Test { Field1 = "Test", Field2 = "Test", Field3 = "Test", Field4 = "Test" });
        GridView.Refresh();
    
        foreach (var Column in Grid1.Columns.Where(b => b.Width.IsStar))
        {
            Column.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
            Grid1.UpdateLayout();
            Column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
            Grid1.UpdateLayout();
        }
    
    }
    
qscott86
  • 303
  • 3
  • 11