I'm using a custom control in an ultragrid column, defined like this :
UltraControlContainerEditor container = new UltraControlContainerEditor();container.RenderingControl = new MyControl(); cols["MyColumn"].EditorComponent = container; cols["MyColumn"].CellDisplayStyle = CellDisplayStyle.FullEditorDisplay;
the grid's row appearance is defined with a gradient like this
UltraGrid.DisplayLayout.Bands[0].Override.RowAppearance.BackColor = System.Drawing.Color.White;UltraGrid.DisplayLayout.Bands[0].Override.RowAppearance.BackColor2 = System.Drawing.Color.FromArgb(191, 219, 255);UltraGrid.DisplayLayout.Bands[0].Override.RowAppearance.BackGradientStyle = Infragistics.Win.GradientStyle.Vertical;
MyControl has a transparent background, and the performance is terrible (scrolling is laggy, resizing the grid takes up to 5 seconds, etc.). If I switch MyControl's backcolor to a plaincolor (eg white), the performance is smooth again.
I've found the performance bottleneck seems to be MyControl's OnPaintBackground method : It seems to be called a ridiculous number of time. Entering a cell results in 3 calls, as does leaving a cell ; scrolling just one row down leads to 3-4 calls to OnPaintBackground for every visible cell, while I would have excepted only one call to the newly visible cell.
Overriding this method and doing nothing in it results in smooth performance, but I've got some visual artefacts here and there, so this doesn't seem to be a viable option.
I've also considered using an ultrapanel as MyControl's background, and applying it the same kind of gradient as the grid does, but It's a nightmare to keep the gradient in sync with the current row (which can be selected, or highlighted, etc.)
Is there something I can do to optimize this ? Is this a known issue ?
Hi,
The way the ControlContainerEditor work is that it has to set the Value on your control and force it to paint every time a cell in the grid paints. For a transparent control, it has to make sure that when your control paints, it paints itself onto a surface that correctly represents what would be underneath it.
So if you scroll the grid, it has to paint at least once for every visible cell.
I'm not entirely sure why it's painting multiple times when a cell enters edit mode - that could be a bug.
Can you post a small sample project demonstrating these issues so we can check it out? It's possible that maybe our code is not as efficient as it could be and we could try to improve it.
Here is a sample ; each time onpaintbackground is called on my UserControl, it just prints the corresponding row number in the textbox on the program form.
You can notice that :
- when the mouse pointer passes over a cell of the MonitoredColumn (without clicking) and leaves it, there's 4 total calls to the OnPaintBackground method.
- If you resize the grid size (using the horizontal splitter) to show a verical scrolling bar, scroll all the way to the bottom of the grid, and then click the "down" arrow at the bottom of the scrollbar, you'll see all the cells of the MonitoredColumn are repainted twice. I would have expected nothing to happen.
- a resizing of the grid also result in a repainting of all cells twice instead of one.
- a resizing of the k column (which doesn't event touches the MonitoredColumn results of two calls on each cell of the MonitoredColumn
I've forwarded this thread over to Infragistics Developer Support so they can write this up for developer review.
Are they going to reply directly on this thread? Do you have an expected time to resolution ?
Thanks !
Unfortunately, what you are trying to do here is pushing the limits of the machine and the DotNet framework. The cells have to paint and painting transparently is more performance intensive than painting a solid background.
I think you were probably on the right track when you mentioned using an UltraPanel and trying to synch it up with the cell's background. This is actually easier than you may realize. You don't have to worry about selected, active, etc. All you have to do is use the ResolveAppearance method on the cell to get the actual on-screen appearance of that cell at any given time. This will account for selection, active, and any other appearance that might be applied to the cell.
Then you just need to copy the AppearanceData properties which apply to the background into the Appearance object of your UltraPanel.
Here is the answer I got for the dev team
"After more deeply research our Developer Team find that this behavior is not an issue. On PaintBackground fires any time a control gets a Paint message from Windows. The ControlContainerEditor has to paint the control which is being used as it's RenderingControl any time it paints a cell. So this method will be called every time when your mouse is over a cell, when you click on a cell, scroll the grid, resize the grid ,it will be called at least once for each visible cell on the screen and possibly several times each. This is an absolutely necessary part of how the ControlContainerEditor functions."
I'm a bit surprised by this answer. The sample I attached clearly shows that the ultragrid behavior is far from optimal in this situation...
If someone else has found some ways to improve the ultragrid's scrolling in conjonction with UltraControlContainerEditors, please let me know !
Hello Brann,
This behavior turns to be a development issue. I have logged to our system as dev issue 37169. I will contact you in your support case to provide you more details, and you can follow the status of this issue if you need any specific information.
Thank you.