GridView column width does not update when changin

2020-03-05 02:40发布

问题:

I have a GridView where I'm setting the ItemsSource in code-behind. All columns in the grid are defined in XAML, and all column widths are "Auto". When I initially set ItemsSource of the grid, the column widths are set correctly.

Now, depending on the user's actions, the ItemsSource of the grid may be set to a new EntityCollection. What I have noticed is that the column widths remain as they were with the previous ItemsSource. That is, the column widths don't seem to adjust themselves automatically when a new ItemsSource is set for the Grid. Is there any way in code-behind or XAML to force the Grid to use the new ItemsSource when setting the column widths? I would think that this would be something that the GridView would do automatically when it's ItemsSource is reset.

<ScrollViewer VerticalScrollBarVisibility="Auto">
    <ListView>
        <ListView.View>
            <GridView>
                <GridView.Columns>
                    <GridViewColumn Width="Auto" Header="Status">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Image Width="16" Height="16" Source="{Binding Path=Blocking}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Width="Auto" Header="Title">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock TextTrimming="CharacterEllipsis" Text="{Binding}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>
</ScrollViewer>

回答1:

Use this code after updating ItemsSource:

public void AutoSizeGridViewColumns(ListView listView) 
{ 
    GridView gridView = listView.View as GridView; 
    if (gridView != null)
    { 
        foreach (var column in gridView.Columns)
        {
            if (double.IsNaN(column.Width))
                column.Width = column.ActualWidth; 
            column.Width = double.NaN; 
        } 
    } 
} 


回答2:

I have created the following class and used across the application whereever 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 column width was set to NaN already, set it ActualWidth temporarily and set to NaN. This raises the property change event and re computes the width.
            if (double.IsNaN(column.Width)) column.Width = column.ActualWidth;
            column.Width = double.NaN;              
        }            
        base.PrepareItem(item);
    }
}