The purpose of this article is to provide some general programming practice guidelines and troubleshooting tips to improve performance when using the UltraWinGrid control. Not all of the tips provided here will apply to every application, but it should help with the most common performance issues a developer is likely to encounter.
If you are concerned about reducing the amount of memory used by the grid, then there are several important things you can do to reduce it.
The grid does not create UltraGridCell objects for every row of data. Cells are only created as neccessary. So whenever possible, you should avoid accessed a cell. For example, suppose your code is using the InitializeRow event of the grid in order to calculate a total. For example:
}
This code references three cells in each row of the grid, thus creating a lot of objects which are potentially unneccessary. This can be avoided using methods on the row to deal with cell values, rather than the cell objects themselves. Like so:
By using the GetCellValue method, we can eliminate 2 cells per row in this example and save memory.
Another common use for the InitializeRow event is to apply an appearance to a cell based on the Value of that cell. Applying an appearance to a cell requires getting a reference to the UltraGridCell, so that is unavoidable. But you can save memory by re-using the same appearance object for multiple cells. Suppose, for example, that you want to change the ForeColor of a cell to red for negative numbers and black for positive numbers. You might do something like this:
This code will create a cell for every row. That is unavoidable, since the cell must be created in order to have an Appearance. The bigger problem here is that the Appearance property on the cell is lazily created. That means that we are not only creating a cell for each row, but a new Appearance object for each row. And since there are only two possible colors, we end up creating a large number of identical appearance objects.
A better way to do this is to create the Appearances we need up front and then re-use the same appearance wherever it is needed.
Another benefit to this approach is that you can change the appearance everywhere en masse. For example, suppose your users want to use Green instead of Black for positive appearances. You could, at run-time, set the ForeColor of the “Positive” Appearance object, and every cell in the grid that was using that appearance would update automatically.
Great article Mike!
i have a first question: Why exist the Value property(i mean the get part of this property) of a cell and GetValueCell method?
thank you
The Value property on the cell is more convenient to use and easier to discover so it makes working with the grid more intuitive. In a case where the cell has already been created, it's easier to use Value then to walk up to the Row and use GetCellValue. Also, you need the Value property for the setter. :)
Hi, I am using the GetCellValue in the following way. I am able to get the value of a cell(where mouse points).
But i am having requirement like, i know the row number and column number, I want to get the value in that cell.
I have tried in so many ways. But I am unable to find the answer. So Please help me. Thanks in advance.
Please find the sample code below.
private void ultraGrid1_MouseMove(object sender, MouseEventArgs e)
{
int lCol = 0;
int lRow = 0;
int absPos = 0;
Infragistics.Win.UIElement aUIElement;
aUIElement = ultraGrid1.DisplayLayout.UIElement.ElementFromPoint(new Point(e.X, e.Y));
UltraGridRow tRow;
UltraGridColumn tCol;
tCol = (UltraGridColumn)aUIElement.GetContext(typeof(UltraGridColumn));
tRow = (UltraGridRow)aUIElement.GetContext(typeof(UltraGridRow));
// if a row was found display the band and row index
if (!(tRow == null))
lRow = tRow.Index + 1;
//MessageBox.Show(tRow.Index.ToString());
else
//MessageBox.Show("No row or column associated");
if (!(tCol == null))
lCol = tCol.Index + 1;
//MessageBox.Show("Col=" + tCol.Index.ToString());
//Wingrid
if (mCurrentSampleObj != null)
absPos = (int)mCurrentSampleObj.get_AbsolutePosition();
if (lCol > 1 && lRow > 0)
string ToolTipText = tRow.GetCellValue(tCol).ToString(); // Gets the text where mouse points(Cell pointed by mouse).
// But here i want to get the value of particular cell(specified column given by us. For example Column =4, Row number will be the same as given above)
toolTip1.SetToolTip(ultraGrid1, ToolTipText);
//arow.Index = lRow-1;
//toolTip1.SetToolTip( ultraGrid1, arow[COL_DESCRIPTIONS - 1].ToString());
else if (lCol == 1 && lRow > 0)
toolTip1.SetToolTip(ultraGrid1, severityImage);
toolTip1.SetToolTip(ultraGrid1, "");
TEMSDatabaseBOM.SAMPLEPOSITION tempint = (TEMSDatabaseBOM.SAMPLEPOSITION)absPos;
mCurrentSampleObj.set_AbsolutePosition(ref tempint);
Hi Pradeep,
In a case like this where you are trying to get the value of a cell under the mouse, it would actually be more efficient to use the Value property of the cell than to use GetCellValue.
The advantage of GetCellValue is that it does not force the creation of an UltraGridCell object. But the cells on the screen are already created. So using GetCellValue doesn't really gain you anything here. In fact, it costs you a little, because you have to call GetContext twice. GetContext is not a terribly expensive operation, but it will save you a little time and code to just use GetContext once to get the UltraGridCell. Then you can get the row from the cell and get any other cell in the row using the Cells collection.
Hi,
I am having some doubt regarding GetContext. I am using this method to get the row and column on mouse move. please find the sample code below.
Infragistics.Win.UIElement aUIElement; aUIElement = ultraGrid1.DisplayLayout.UIElement.ElementFromPoint(new Point(e.X, e.Y)); UltraGridRow tRow; UltraGridColumn tCol; tCol = (UltraGridColumn)aUIElement.GetContext(typeof(UltraGridColumn)); tRow = (UltraGridRow)aUIElement.GetContext(typeof(UltraGridRow));
int lRow = tRow.Index; int lCol = tCol.Index;
Its working fine. But when i place my mouse on Column header, it is giving row number(lRow) as '0'.
It is giving Column header as Row '0' and 1st row also as row '0'.
Please help me out. Its urjent requirement. How to catch whether mouse is clicked on column header or not( I need to sort the column when i click on column header).
regards,
Pradeep
Did you read my previous post? I suggest that you use GetContext to just get the cell instead of the row.
Anyway, the colmun headers DO have a context of the first row. This is correct. So what you would have to do to get the row it use GetAncestor on the UIElement and get a RowUIElement before you call GetContext. If the RowUIElement is null, then you know you are not on a row.
Hi Mike,
Thanks for the reply. I have read your previous post, but little bit confused. Now I got the solution from your reply. Now i am using GetContext for cell. Its working fine for me.
Regards,
Pradeep.