JohnG79
JohnG79

Reputation: 1605

WPF XAML Strange column width behaviour

The following DataGrid begins with thin columns then quickly springs out to the defined widths in the XAML below.

How can we make the column widths as described, from the outset, without the initial behaviour?

            <DataGrid ItemsSource="{Binding Orders}" Name="_dataGridOrders" AutoGenerateColumns="False">

                <DataGrid.Columns>

                    <DataGridTextColumn Header="Order Number" Binding="{Binding OrderNumber}" Width="3.3*"/>
                    <DataGridTextColumn Header="Numeric ID" Binding="{Binding NumericId}" Width="3*"/>
                    <DataGridTextColumn Header="Ship To" Binding="{Binding ShipTo}" Width="4*"/>
                    <DataGridTextColumn Header="Order Date" Binding="{Binding OrderDate}" Width="5*"/>
                    <DataGridTextColumn Header="Calculated Weight" Binding="{Binding CalculatedWeight}" Width="4*"/>
                    <DataGridTextColumn Header="# Items" Binding="{Binding ItemsNumber}" Width="3*"/>
                    <DataGridTextColumn Header="Tracking" Binding="{Binding TrackingNumbers}" Width="6*"/>

                </DataGrid.Columns>

            </DataGrid>

Upvotes: 0

Views: 206

Answers (1)

AQuirky
AQuirky

Reputation: 5266

I am guessing a bit here because you haven't provided all the relevant code, but I feel pretty certain I know what the problem is.

The reason the DataGrid is starting with thin columns that expand to the expected size is that you are going through multipe layout passes on the grid. This is most likely due to the fact that you are changing the window size after he window becomes visible. The reason you might do this is to restore the window size to the size of the last execution of the app. If you do this in the window constructor you will get the flickering you report. To fix this move the resize code to the window initialized event handler.

So instead of this...

    public MainWindow()
    {
        InitializeComponent();
        Rect r = App.Settings.MainWindowBounds;
        Rect desktop = new Rect(SystemParameters.VirtualScreenLeft, SystemParameters.VirtualScreenTop, SystemParameters.VirtualScreenWidth, SystemParameters.VirtualScreenHeight);
        if (desktop.Contains(r) && r.Width > 0.0 && r.Height > 0.0)
        {
            Left = r.Left;
            Top = r.Top;
            Height = r.Height;
            Width = r.Width;
        }
    }

Do this...

    private void Window_Initialized(object sender, RoutedEventArgs e)
    {
        Rect r = App.Settings.MainWindowBounds;
        Rect desktop = new Rect(SystemParameters.VirtualScreenLeft, SystemParameters.VirtualScreenTop, SystemParameters.VirtualScreenWidth, SystemParameters.VirtualScreenHeight);
        if (desktop.Contains(r) && r.Width > 0.0 && r.Height > 0.0)
        {
            Left = r.Left;
            Top = r.Top;
            Height = r.Height;
            Width = r.Width;
        }
    }

This is a much more efficient approach since the window initialized handler is called before the layout pass.

Upvotes: 1

Related Questions