Hi I have huge set of data to load and format conditionally (400k+ rows and 100+ columns)
I'm using InitRow event and shared Appearance object, as explained here:
https://es.infragistics.com/community/forums/f/ultimate-ui-for-windows-forms/15306/wingrid-performance-guide
But still getting Out of Memery exception (my PS has 16Gb mem + 30 Gb Swap...)
Do you know any solution for that ?
Maybe there is an on option to perform conditional formatting *ONLY* for displayed rows / cells, instread all dataset ?
EDIT
tested on both v. 18.2 and 19.1V. 19.1 throws Out of Memory error even quicker then 18.2 ...
Hello Maceij,
Thank you for contacting Infragistics. Are you implementing Conditional Formatting in the manner we describe in our online documentation?https://es.infragistics.com/help/winforms/wingrid-using-conditional-formattingFrom my understanding hooking InitializeRow is not as efficient as applying appearances and conditions to a ConditionValueAppearance.
Hello Michael,
As I mentioned earlier - I;m using InitializeRow method, using your performance guide (as I didnt find other way to archive that..)
I'll be happy to try conditional formatting, but in my case condition is not such static (eg column1_value > 5).I do need perform some simple lookup based on other cells value in current row
/Basically what my "conditional formatting" function is doing is checking if external hash table contains analyzed column name (in relation to other 'row key' column) and if does it set RED background (read by end user as 'ERROR')/
It works pretty much well for smaller dataset but larger consumes a lot of memory (I guess because many cells references to appearance object) - see screen below. I was a bit surprised because I have a lot RAM + hdd swap - it should be more than enough to handle even bigger datasets
So I was searching option to show set Appearance only for displayed rows but remove for those not being shown.
EXAMPLE CODE:
CondFormatOoM.zip
I confirm DrawFilter usage resolved this issue - thanks !
Also I found that Out Of memory issue will not occur if app will be built as 64bit (instead x86/any CPU).
However I prefer to use DrawFilter as it gives much better performance / end user experience
Hi Mike
Many thanks for your reply. Will try this approach and let you know if works
I know how it might look loading such massive data to grid, but this is very strict project requirement and has solid business case for such approach (believe me ive triple checked rationale behind...)
Ofc I can do similar thing using standard. Net components but I'd prefer to stick with infragistics :)
If your conditions are complex and require you to write code, then the ConditionFormatting functionality probably won't be sufficient.
Another approach you could take is using a DrawFilter. The advantage of the DrawFilter is that it only applies to the drawing layer. So it will only apply to cells that are actually on the screen.
It's a little tricky because different cells may use different elements to draw their background or foreground, depending on the editor the cell is using. But for the most part, the DrawFilter would look something like this:
public class MyDrawFilter : IUIElementDrawFilter { public bool DrawElement(DrawPhase drawPhase, ref UIElementDrawParams drawParams) { var cell = drawParams.Element.GetContext(typeof(UltraGridCell)) as UltraGridCell; if (null == cell) Debug.Fail("Failed to get a cell; unexpected."); else { switch (cell.Column.Key) { case "Int32 1": int cellValueAsInt = (int)cell.Value; if (cellValueAsInt > 2) { drawParams.AppearanceData.BackColor = System.Drawing.Color.Green; drawParams.AppearanceData.ForeColor = System.Drawing.Color.White; } else { drawParams.AppearanceData.BackColor = System.Drawing.Color.Red; drawParams.AppearanceData.ForeColor = System.Drawing.Color.Yellow; } break; } } return false; } public DrawPhase GetPhasesToFilter(ref UIElementDrawParams drawParams) { if (drawParams.Element is EmbeddableUIElementBase) return DrawPhase.BeforeDrawElement; return DrawPhase.None; } }
And, of course you have to attach an instance of this class to the grid. I would do this in the form constructor or some other event that only fires once before the grid paints.
this.ultraGrid1.DrawFilter = new MyDrawFilter();
Having said that, showing such a massive set of data in the grid probably isn't a good idea. There are a lot of other operations that will fore the grid to load all of the rows and cell, such as filtering, sorting, printing, etc. And any f these will cause a serious performance hit in your application. You must be seeing a huge hit when you load that much data into the application, and another one when you bind the grid, even without the InitializeRow code.
Also, no human used could possibly work with that much data at once in any useful way. You might want to consider implementing some kind of query interface where the user specifies some search criteria and you only pull down a subset of your data that they can work with.