This is a migrated thread and some comments may be shown as answers.

RadGridView's DataBindingComplete event handler in a async context and with the Telerik's WinForm RadGridView BestFitColumns method

1 Answer 717 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Bruno
Top achievements
Rank 1
Bruno asked on 21 Jun 2016, 01:53 PM


Hi,

I'm having some problems with the RadGridView's DataBindingComplete event handler in a async context and with the Telerik's WinForm RadGridView BestFitColumns method.

I'm developing an winforms with Telerik application that loads data from several db tables and shows them in distinct RadGridViews (one for each table source).
Each of the grids is inside a DocumentWindow. Each DocumentWindow is inside DocumentContainer and all of the DocumentContainers are under a single aggregating Docking.DocumentTabStrip.

The process db table information process is asyncronous so that the UI is free allowing the user to see the information in one table when it becomes available even if one of the other tables are still being loaded.

The first problem is that the DataBindingComplete is only triggered when the user selects the respective tab. Since some of the DataBindingComplete logic can be quite time consuming it leads to a undesired user experience until the data is finally presented.
Is there an alternative event that can be triggered when the data is already available in the RadGridView but without the need of having the user triggering it?

The second is with the way the BestFitColumns method determines the column width. The native DataGridView column's AutoSizeMode contains a option of AllDataCellsExceptHeader that I'm unable to emulate in Telerik.
The documentation for these options is rather scarce and all of the tried options fall short.
Of the available options the closest are the AllCells, DisplayedCells and DisplayedDataCells as the others do not take in account the cell's values.
The AllCells and DisplayedCells use the column headers as input and that makes data spread out too much, which is undesired.
The closest is DisplayedDataCells that sort of works but the logic seems to only use the cells in the rows in the visible range. (I.E.: the rows presented when the grid is presented in the UI). Trying to explain better, if form only displays the first Nth data rows, after the method runs the data will be visible correctly formatted, but if the (N+1) row data has a width larger than any of the first Nth rows the displayed data will be truncated and suffixed with the "..". Is there a way to emulate the AllDataCellsExceptHeader at all?

Thanks for your help.

Regards,

I've implement it using the following logic (snipped code).

(..)
  private async void displayButton_Click (object sender, EventArgs e) {
  (..)
    await Task.Run(() => Parallel.ForEach(tablesToRetrieve.Keys, tableID => {
      (..)
      DocumentWindow docWindow = ((DocumentWindow)returnedDataDocumentTabStrip.Controls[tableName]);
       
      if (GetDBTableData(tableID, tableArguments, out dataTable)) {
        docWindow.Invoke((Action)delegate {
          docWindow.Controls.Add(newRadView(dataTable));
          docWindow.Refresh();
        });
      }
      (..)
    }));
  }
  (..)
  private RadGridView newRadView(DataTable dTable) {
  
    RadGridView gridView = new RadGridView();   
    gridView.AutoSizeRows = false;
    gridView.AllowAutoSizeColumns = true;
    gridView.ReadOnly = true;
    gridView.AutoExpandGroups = true;
    gridView.AllowAddNewRow = false;
    gridView.AllowDeleteRow = false;
    gridView.AllowColumnReorder = true;
    gridView.AllowColumnResize = true;
    gridView.MultiSelect = true;
    gridView.SelectionMode= GridViewSelectionMode.CellSelect;       
    gridView.EnableFiltering = true;
    gridView.MasterTemplate.EnableFiltering = true;       
    gridView.ShowHeaderCellButtons = true;
    gridView.EnableAlternatingRowColor = true;
    gridView.EnableGrouping = true;
    gridView.MasterTemplate.EnableGrouping  =true;
    gridView.EnableSorting = true;
    gridView.MasterTemplate.EnableSorting = true;       
    gridView.TableElement.AlternatingRowColor = Color.FromArgb(240, 240, 240);
    gridView.TableElement.RowHeight = 18;
    gridView.ShowFilteringRow = true;
    gridView.Dock = DockStyle.Fill;       
    gridView.AllowSearchRow = true;       
    gridView.SearchRowPosition = SystemRowPosition.Bottom;
    gridView.MasterTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.None;   
    gridView.Name = dTable.TableName;
     
    /* Arm events handlers   
    gridView.ViewCellFormatting += gridView_ViewCellFormatting;
    gridView.DataBindingComplete += gridView_DataBindingComplete;
    gridView.ToolTipTextNeeded += gridView_ToolTipTextNeeded;
 
    /* Load dataTable data */
    gridView.BeginUpdate();
    gridView.DataSource = new BindingSource(dataTable, null);
     
    /* Customize table sort assumptions */   
    gridView.SortDescriptors.Add(new SortDescriptor("DUMMY_COLUMN", System.ComponentModel.ListSortDirection.Descending));
     
    gridView.EndUpdate(true);
     
    return gridView; 
  }
  (..)
  private void gridView_ViewCellFormatting(object sender, CellFormattingEventArgs e) {
    if (e.CellElement.GetType() == typeof(GridHeaderCellElement))
      e.CellElement.TextWrap = true;
  }
  (..)
  private void gridView_DataBindingComplete(object sender, GridViewBindingCompleteEventArgs e) {
    RadGridView gridView = (RadGridView)sender;
     
    /* Show/Shift/Hide columns to display */
    (..)
     
    /* Finally Adjust columns to it's data */
    gridView.BestFitColumns(BestFitColumnMode.DisplayedDataCells);
  }

1 Answer, 1 is accepted

Sort by
0
Hristo
Telerik team
answered on 22 Jun 2016, 08:46 AM
Hello,

Thank you for writing.

The DataBindingComplete event does not fire because you are dynamically creating the grid controls and adding them to a page which is not yet visible. Please check the following threads discussing a similar scenario: The experienced behavior is not related to the async data load. You can work around it by calling the CreateControl method which is inherited by the System.Windows.Forms.Control class. This will force the handle of the grid to be created and the event will be raised. Please check my code snippet below:
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
 
    private async void radButton1_Click(object sender, EventArgs e)
    {
 
        Func<RadGridView> job = new Func<RadGridView>(this.BindGrid);
        Task<RadGridView> task = new Task<RadGridView>(job);
        task.Start();
 
        RadGridView grid = await task;
        grid.CreateControl();
 
        this.documentWindow1.Controls.Add(grid);
    }
 
    private RadGridView BindGrid()
    {
        DataTable dataTable = new DataTable();
        dataTable.Columns.Add("Id", typeof(int));
        dataTable.Columns.Add("Name", typeof(string));
        dataTable.Columns.Add("IsValid", typeof(bool));
        dataTable.Columns.Add("Date", typeof(DateTime));
 
        for (int i = 0; i < 50000; i++)
        {
            dataTable.Rows.Add(i, "Name " + i, i % 2 == 0, DateTime.Now.AddDays(i));
        }
 
        RadGridView gridView = new RadGridView();
        gridView.Dock = DockStyle.Fill;
        gridView.DataBindingComplete += gridView_DataBindingComplete;
        gridView.DataSource = dataTable;
 
        return gridView;
    }
 
    private void gridView_DataBindingComplete(object sender, GridViewBindingCompleteEventArgs e)
    {
        RadGridView gridView = (RadGridView)sender;
        gridView.MasterTemplate.BestFitColumns(BestFitColumnMode.DisplayedDataCells);
    }
}

Regarding you second question, the DisplayedDataCells value of the BestFitColumnMode enumeration measures the columns according to the size of the currently visible data cells excluding the headers. This is the behavior by design because measuring all cells at once would deteriorate the performance of the control. If it fits your local setup you can subscribe the grid`s vertical scrollbar to the ValueChanged event and call the BestFitColumns method in the handler. A similar question has been discussed here: http://www.telerik.com/forums/dynamically-bestfit-columns-as-user-scrolls-a-grid.

I hope this helps. Should you have further questions please do not hesitate to write back.

Regards,
Hristo Merdjanov
Telerik
Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
Tags
GridView
Asked by
Bruno
Top achievements
Rank 1
Answers by
Hristo
Telerik team
Share this question
or