How to force DataGrid to rebuild VisualTree for it

2019-09-19 09:48发布

问题:

I have WPF form with DataGrid. New columns can be added to the datagrid manually by user via button. This is the code to add new column:

        private void ColumnAdornerAddButton_MouseDown(object sender, MouseButtonEventArgs e)
    {
        DataGridTextAdornerColumn column = new DataGridTextAdornerColumn();
        column.Header = "New column";
        column.HeaderStyle = (Style)FindResource("columnHeader");
        column.AdornerTemplate = (DataTemplate)FindResource("columnAdorner");
        Binding binding = new Binding("Data");
        binding.Mode = BindingMode.TwoWay;
        column.Binding = binding;

        grid.Columns.Insert(grid.Columns.Count - 1, column);

        //Add adorner
        DataGridColumnHeader header = GetColumnHeaderFromColumn(column);
        AddAdorner(header, column.AdornerTemplate, column.IsReadOnly);
    }

    private DataGridColumnHeader GetColumnHeaderFromColumn(DataGridColumn column)
    {
        // dataGrid is the name of your DataGrid. In this case Name="dataGrid" 
        List<DataGridColumnHeader> columnHeaders = GetVisualChildCollection<DataGridColumnHeader>(grid);
        foreach (DataGridColumnHeader columnHeader in columnHeaders)
        {
            if (columnHeader.Column == column)
            {
                return columnHeader;
            }
        }
        return null;
    }

The problem is that after I have added the column to the grid its header is not yet generated and it is not present in visual tree. Thus I cant get header for the new column and apply adorner to it. I have tried to call ApplyTemplate recursively on visual tree of the grid without any luck.

Is there any way to force grid to generate DataGridColumnHeader for the new column in code?

Thank you in advance.

回答1:

Hi after adding columns to datagrid call the method UpdateLayOut() of DataGrid.

datagrid.UpdateLayout();

I hope this will help.



回答2:

I just want to enhance the solution, The method
datagrid.Items.Refresh(); will helps to recreate the view (Datagrid). thus you can see the updated value in datagrid