I’m struggling to workout what the relationship is with CellUIElement and the UltraGridCell. I understand that you can derive the UltraGridCell from the GetContext method of the CellUIElement, but how are the two related? Can someone please explain the relationship beween these objects and how and when they are created.
Kind Regards,
Tim
Hi Tim,
Hm... the distinction is pretty clear in my minds, but I am finding it a bit difficult to put into words.
The UltraGridCell represents a cell in a row. It has properties related to the cell, such as the Value, a reference to the column, a Style, a Hidden property, etc.
The UIElement is a visual representation of the cell and contains the child elements that make up that cell on the screen (and potentially in a printed document, as well). UIElements are a concept that is part of the Infragistics WinForms Presentation Layout Framework. Everything you see on the screen in any of the WinForms controls is handled by UIElements.
Most of the time, you really don't need to use UIElements at all. They are there to provide a framework for drawing controls and objects and they can be used to provide advanced extensibility if you need to do something that the control doesn't ordinarily do.
You might get a better understanding of UIElements if you check out the Infragistics UIElementViewer Utility
Hi Mike,
Thanks for your reply. I’ve already used UIElementViewer so have a basic understanding of the UIElement hierarchy within the UltraGrid model. I guess the best way to understand my issues is to consider attempting to write replacement objects for UltraGridCell and CellUIElement.
1) I understand how to create and embed custom UIElements using a creation filter; however I do not understand how you are able to derive the appropriate UltraGridCell from the CellUIElement. Is there simply a reference from one object to another, does one inherit from the other or does it use the row and column information to derive the correct UltraGridCell. I’ll need to copy this behavior in my model so should really understand how the GetContext method really works.
2) Could you point me in the direction of where I can find out more information about the drawing of custom UIElements as I’m currently drawing my UIElement object by overriding the DrawBorders method after inheriting from UIElement directly? This has some funny behaviours when expanding the row height as these objects may disappear from the screen but do still exist within the grid hiarchy. Is there a specific method that I should be overriding to control the drawing of my object? Note: I’m not currently using a draw filter.
3) Is it possible to derive the appropriate column key from the RowCellAreaUIElement within a creation filter so that I can replace the existing CellUIElements with my own UIElements?
Thanks again for all your help.
Regards,
I'm wracking my brain here, but I'm finding it extremely difficult to answer your questions here without knowing what you are trying to do. Perhaps it would be better if you explained what you want to accomplish and I can point you in the direction of how best to accomplish it.
We have an existing system which utilises an UltraGrid to display appointment information for a number of resources as shown in the following diagram.
The bookable day is divided up into units of time with an appointment spanning one or more units. The grid is build to represent this with each of the columns on the right-hand-side representing one of these units of time. This functions adequately when the unit of time is 30 minutes or more, however when this is reduced to 5 minutes or less the grid will draw several tens of columns to represent a single day, and as you can image, runs slowly when displaying several days. We have read several articles on improving the performance of the grid and have attempted to optimise this solution to the best of our abilities, however we need to rethink this approach and redesign the display.
I would prefer to represent the bookable day as a single cell within the grid so that the grid draws quickly, with minimal overheads. I was hoping to achieve this by creating a UIElement which will display the appointment information for each day per resource. i.e. draw squares within the cell to represent each appointment based on how much a single pixle represents in terms of time.
I believe that I need a single UIElement to represent the bookable day (i.e. 8am-5pm) which holds child appointment UIElements (the squares) which are placed at specific locations within the bookableDayUIElement's borders.
The UltraGrid will therefore have a hierarchy similar to this …
UltraGridUIElement
DataAreaUIElement
RowColRegionIntersectionUIElement
RowUIElement
RowCellAreaUIElement
CellUIElement
BookableDayUIElement
AppointmentUIElement
I’d had it in mind to have an object which manages the BookableDay and which holds a collection of Appointment objects. These would then somehow return their respective BookableDayUIElement and AppointmentUIElement within a creation filter which would handle the drawing of these objects to the GUI.
I would like to further enhance this interface at a later stage by extending the functional and allowing the appointment object to be adjustable by inheriting from the AdjustableUIElement so that they can be expanded or contracted, and thus modifying any surrounding appointment times to fall into line.
In summary I’d like to create my own control and embed this within the grid cell, but really don’t know enough about the structure of your controls to allow me to create and embed my own representation.
Thanks again fro your help,
Brilliant ... Thanks Mike I'll post an example solution if I get stuck so you’ll have a clearer picture of where I am and so that others can learn from my experimentation.
Okay, now it all makes sense. Creating a BookableDayUIElement and placing it inside the cell is an excellent idea.
So the basic approach you would take is to define your two elements, which derive from UIElement. Let's ignore the Adjustable aspect of this for right now.
You would use a CreationFilter and handle the BeforeCreateChildElements for the CellUIElement. You use GetContext on the element to get the UltraGridCell, and use the cell's Column and Row, and Value properties to determine what to display inside that cell. For most cells, you would do nothing. For the cells in the day columns, you would check the ChildElements collection on the CellUIElement to see if it already has a BookableDayUIElement in it. If it does, you can re-use the same element for efficiency. If not, you create a new one. Note that if you re-use the same one, you will probably need to re-initialize it based on the cell's current value, since it might have changed.
Anyway... that's it as far as the grid is concerned. The CreationFilter does not need to do anything else.
The creation of the AppointmentUIElement would be done in the PositionChildElements method of the BookableDayUIElement, which you would override. To get the cell, BookableDayUIElement can simply call GetContext on itself. Since it's contained inside a CellUIElement, this should work. Once you have the cell, of course, you have it's Value, Column, and Row, so you can position the AppointmentUIElements as you see fit. Once again, it's a good idea to check the ChildElements collection of the BookableDayUIElement for already-existing AppointmentUIElements and re-use them if they are there. Also, you would set some properties on each AppointmentUIElement so it knows what color to use.
To handle the color of the AppointmentUIElement, you would override it's InitAppearance method and resolve the AppearanceData properties.
Anyway, that's the general approach I would take. Let me know if you get stuck and need a push in the right direction.