Hi,
I'm using infragistic's grid for add-in app in AutoCAD. Usually the amount of data is very large (20.000-100.000 or even more). By default I use load on demand technique, which is very fast and works just great, but ... I had to disable almoust all the features of grid (group by, filter sort ...), so I made the other option, whitch preloads all data in datatable. With code above I add image columns for zoom, edit, attach ... and found out that this is the problem. Even if I load all records (in advanced mode), when user uses filter or group by or and other functionallity that needs all rows, grid becomes very slow and imposible to use. If I comment all the code in InitializeRow event, that doesn't happen. Should I draw images in cell on any other event, or could I get any property of e.Row object which would tell me if row is actually visible? I tried with property e.Row.VisibleIndex (in InitializeRow event), but I allways get value -1.
On web I am using ExtJs's Grid, which has great feature called ActionRow. That enables me to add some actions (string - action key, image - action image, string - function name), and grid automaticly adds column with images. If user clicks the image, function fires.
If Infragistics Grid would have feature like that, that would be amazing.
I would like to thank for any answer in advance!
//I call this void on InitializeLayout event of grid.
public static void AddImgColumn(ColumnsCollection columns, string colKey, bool addToEnd)
{
if (!columns.Exists(colKey))
UltraGridColumn col;
if (addToEnd)
col = columns.Add(colKey);
else
col = columns.Insert(0, colKey);
col.Width = 20;
col.AllowRowFiltering = DefaultableBoolean.False;
col.AllowRowSummaries = AllowRowSummaries.False;
col.AllowGroupBy = DefaultableBoolean.False;
col.ExcludeFromColumnChooser = ExcludeFromColumnChooser.True;
col.CellActivation = Activation.NoEdit;
col.CellClickAction = CellClickAction.CellSelect;
col.Style = Infragistics.Win.UltraWinGrid.ColumnStyle.Image;
col.Header.Caption = "";
col.Header.Fixed = true;
}
//This void I call on InitializeRow event of grid
if (row.Cells.Exists(columnKey))
row.Cells[columnKey].Appearance.ImageBackground = bmp;
row.Cells[columnKey].Appearance.Cursor = System.Windows.Forms.Cursors.Hand;
if (tooltip != null)
row.Cells[columnKey].ToolTipText = tooltip;
private void ugMain_InitializeRow(object sender, InitializeRowEventArgs e)
UltraGridUtils.SetCellImage(e.Row, Globals.ZoomColumnKey, Kaliopa.AutoCAD.FDO.DataGrid.Properties.Resources.zoomfeature, "Prikaži v risbi");
UltraGridUtils.SetCellImage(e.Row, Globals.EditRowColumnKey, Kaliopa.AutoCAD.FDO.DataGrid.Properties.Resources.ROW_EDIT, "Uredi podatke");
UltraGridUtils.SetCellImage(e.Row, Globals.RelationsColumnKey, Properties.Resources.table_relationship, "Prikaži podatke povezanih tabel");
if (e.Row.Cells.Exists(Globals.AttachmentsColumnKey))
if (e.Row.GetCellValue(Globals.colPriponke) != DBNull.Value)
e.Row.Cells[Globals.AttachmentsColumnKey].Appearance.ImageBackground = Kaliopa.AutoCAD.FDO.DataGrid.Properties.Resources.attachments_ADDED;
e.Row.Cells[Globals.AttachmentsColumnKey].Appearance.ImageBackground = Kaliopa.AutoCAD.FDO.DataGrid.Properties.Resources.attachments;
e.Row.Cells[Globals.AttachmentsColumnKey].Appearance.Cursor = Cursors.Hand;
// I call this void in InitializeLayout event, based on the type of grid user selects
#region DisplaySettings
public static void SetLoadOnDemandSettings(UltraGrid grid)
grid.DisplayLayout.LoadStyle = LoadStyle.LoadOnDemand;
grid.DisplayLayout.ScrollStyle = ScrollStyle.Immediate;
grid.DisplayLayout.ScrollBounds = ScrollBounds.ScrollToFill;
grid.DisplayLayout.ViewStyleBand = ViewStyleBand.Vertical;
grid.DisplayLayout.ViewStyle = ViewStyle.SingleBand;
grid.DisplayLayout.Override.AllowGroupBy = DefaultableBoolean.False;
grid.DisplayLayout.Override.AllowRowFiltering = DefaultableBoolean.False;
grid.DisplayLayout.Override.HeaderClickAction = HeaderClickAction.Select;
public static void SetAdvancedSettings(UltraGrid grid)
grid.DisplayLayout.ViewStyleBand = ViewStyleBand.OutlookGroupBy;
grid.DisplayLayout.Override.AllowGroupBy = DefaultableBoolean.True;
grid.DisplayLayout.Override.AllowRowFiltering = DefaultableBoolean.True;
grid.DisplayLayout.Override.HeaderClickAction = HeaderClickAction.SortMulti;
#endregion
I'm afraid you lost me. Which part of this is causing a performance problem?
Are you saying that simply having an image on the cell is causing a problem? If so, when does this problem occur. You mentioned sorting and filtering, but that has nothing to do with images in a cell.
Have you read the WinGrid Performance Guide? The guide has a section dedicated to how to use appearances most efficiently.
Problem is in code, that is in InitializeRow event. When I check if column exists and set the cell image, as I posted before. If I comment this lines out, everything works just fine.
This happens when I click sort, group by, filter ... when all rows in grid are initialized.
If somehow I could find out if row is in grid's visible rectangle, maybe that would solve my problem.
Did you check out the WinGrid Performance Guide?
The code in you have here is very inefficient. You are getting the Appearance object multiple times on every cell and you are calling the Exists method on every row's Cells collection.
You could make this code a lot more efficient by re-using a small set of Appearance objects, instead of setting the same image on a large number of appearances.
You could also speed things up by only calling Exists once and then keeping a flag once it gets set to true. Assuming you are not setting the grid's DataSource to null or something with a completely different structure, the cell will always exist once it exists for the first time. So you could avoid iterating the cells collection by just keeping a flag.
In any case, if that doesn't help or if you really want to make this super-efficient, then your idea of only applying the images to the cells on the screen is a good one. To do that, what you would do is apply a blank or transparent image of the appropriate size to the CellAppearance of the column(s) that will have images.
Then you could use a CreationFilter to set the image on the ImageUIElement of the cell, instead of using InitializeRow.
Looks like I posted almost the same CreationFilter in another thread:
Cannot set Image when using DrawFilter - Infragistics Community
slavkog said: Maybe I could optimize this code a little bit if I would create only one column named "GridActions" and add all needed images with some keys to this column? In OnClick event I would then only check which image user clicks and execute some action based on the key of image.
Maybe I could optimize this code a little bit if I would create only one column named "GridActions" and add all needed images with some keys to this column?
In OnClick event I would then only check which image user clicks and execute some action based on the key of image.
I'm not sure I follow you here. How would having only one column help?
I have modified my code with logic that you have suggested and now grid works much faster.
When program starts I create new Appearance objects. In InitializeLayout event I check which columns exist and set some variables to true/false.
In InitializeRow Event I check those variables and set cell Appearance to object created on program start.