Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
175
Performance hit when setting cell.ValueList in InitializeRow (or how to suspend repainting?)
posted

I have a bound grid with several columns. One column is a custom drop-down list. Items of list depend on row data (varies from row to row). 

Setup of such column is performed in InitializeRow event by creating ValueList, adding required items (with correct one which corresponds to bound data), and setting this ValueList to required column's cell with cell.ValueList = list. 

When grid is shown for the first time and data (around 1200 rows) is bound, SetDataBinding executes in no time (<0,1s) (it is possible that data is bound while grid is not visible yet).

But, if other data of the same amount is bound to the same grid, SetDataBinding blocks for about 20s.

I've analyzed execution with performance profiler and found that while setting value list to cell - cell.ValueList = list - redraw/invalidation of the grid is invoked which slows down performance:

Infragistics.Win.ControlUIElementBase.VerifyIfElementsChanged(Boolean, Boolean), 
Infragistics.Win.UIElement.VerifyChildElements(Boolean)
Infragistics.Win.UltraWinGrid.UltraGridUIElement.VerifyChildElements(ControlUIElementBase, Boolean)
... etc

If I comment out  cell.ValueList = list; line, grid is bound in milliseconds every time.

Code of setting cell.ValueList is executed in BeginUpdate/EndUpdate of grid.
I've tried several other options (SuspendRowSynchronization, BeginInit, even grid.Visible = false) but with no luck.

I suspect that after data is bound to a grid for the first time or grid is drawn for the first time, any subsequent bindings/redraws are not suspended in the same way? 

Is there any way to suspend all grid repainting/invalidating and invoke them after all cell.ValueList's are set? Or somehow suspend cell.ValueList invalidations?

Parents Reply
  • 175
    posted in reply to Mike Saltzman

    Hey Mike,

    Thank you, I was able to implement required functionality with single UltraDropDown, no more performance issues.

    But, there are several questions about styling.

    In the end of post I'll paste some code, which made UltraDropDown behave more like standard ValueList, end result looks like this:

    First row is active selected value (we have background image stretched), 4th row - HotTrack'ed (HotTrackRowCellAppearance.BackColor set).

    Standard ValueList looks like this:

     

     

    How do I achieve the following:

    a) We use AppStylist and GridRow role has Selected/Active states with background images. How to reset/override these images, so UltraDropDown would show not image, but ValueList style (orange color with border) for Selected/Active row. Resetting/clearing e.Layout.Override.ActiveRowAppearance, SelectedRowAppearance background on UltraDropDown did not help - or I've reset incorrect properties.

    b) How to achieve border around hot-tracked UltraDropDown item, as seen in ValueList.

    c) How to properly share code in forum - with tabs, syntax highlight, etc :)



    Here is the code I've used so far (maybe some will find it usefull):

     

    In UltraDropDown initialize layout:

    e.Layout.BorderStyle = UIElementBorderStyle.Rounded1;

    e.Layout.Override.BorderStyleCell = UIElementBorderStyle.None;
    e.Layout.Override.RowAppearance.BorderAlpha = Alpha.Transparent;

    e.Layout.ScrollStyle = ScrollStyle.Immediate;
    e.Layout.Scrollbars = Scrollbars.Vertical;

    e.Layout.Appearance.BackColor = Color.White;
    e.Layout.Override.HotTrackRowCellAppearance.BackColor = Color.FromArgb(255, 171, 63);

    e.Layout.AutoFitStyle = AutoFitStyle.ExtendLastColumn;

     


    Main creation filter method for UltraDrop down to size/position correctly:

    void IUIElementCreationFilter.AfterCreateChildElements(UIElement parent)
    {
        if (parent is UltraGridUIElement)
        {
            UltraGridUIElement gridUiElement = (UltraGridUIElement)parent;

            // Get drop down control:
            Control dropDownControl = gridUiElement.Control.Parent;

            // Get active cell from where drop-down is invoked:
            UltraGridCell cell = this.gridControl.ActiveCell;

            // This method is called more than once, the first time the drop-down section
            // is not attached to the UIElements, which explains this "if".
            if (dropDownControl != null && cell != null)
            {
                // Calculate maximum width of drop-down by drop-down column width:
               UltraGridColumn dropDownColumn = null;
               UltraGridLayout layout = gridUiElement.Grid.DisplayLayout;if (layout.Bands.Count > 0)
               {
                   // Get drop-down grid column:
                   if (layout.Bands[0].Columns.Exists(this.columnName))
                        dropDownColumn = layout.Bands[0].Columns[this.columnName];
               }

               int width = -1;
             
               // Get column widht:
              if (dropDownColumn != null)
              {
                   width = dropDownColumn.CalculateAutoResizeWidth(PerformAutoSizeType.VisibleRows, false);
                   width += 25; // Scroll bar width ~ should be get from somewhere?
               }

               // Get UI element of active cell:
               UIElement cellElement = cell.GetUIElement();
               if (cellElement != null)
               {
                   Rectangle cellRect = cellElement.Rect;

                   // If cell width is more than required for drop-down control, expand drop-down:
                   if (cellRect.Width > width)
                             width = cellRect.Width;

                   // Set drop-down width:
                   dropDownControl.Width = width;

                   // Calculate drop-down location:
                   Point location = new Point(cellRect.Right - width, cellRect.Bottom);
                   location = this.gridControl.PointToScreen(location);

                   // Set drop-down location:
                   dropDownControl.Left = location.X;

                 }

            }

       }

    }

     

Children