Dapfor .Net Grid Introduction
Part1: Data Types
Part2: Data Binding
Part3: Event-driven model
Part4: Data formatting and presentation
Part5: Threadsafety
Part6: Threadsafe BindingList
Part7: Appearance and painting
Part8: Cell highlighting
Part9: Data filtering
Part10: Data sorting
Part11: Data grouping
Part12: Headers and columns
Part13: Editors
Part14: Performance. Practical recommendations
Part15: Real-time blotter
Part16: Currency converter
Part17: Instrument browser
Part18: Order book
Part19: Basket Viewer
.Net Grid tutorial Part 8: Cell highlighting
Almost any modern financial application that works in real time should be able to highlight dynamically changing data. This becomes especially important with continuous growth of data volumes and increasing market volatility. There are many examples of highlighting, e.g. change of cell background color for specified time on item price change or change of risks calculated in real time.
Highlighting of grid cells with quickly changing information requires understanding of the painting system in OS Windows and ability to maximize highlighting efficiency while minimizing consumption of CPU and memory resources.
To understand difficulties that may be encountered by programmers, let’s first look at the painting system in Windows. As you know, it is asynchronous. First, repainted area is defined with
Control.Invalidate(Rectangle) method, and then Windows generates
WM_PAINT message that directly performs repainting of cell content.
Now let’s see, what a programmer should do to correctly implement data highlighting system in a regular grid.
- When a data cell needs to be highlighted for certain time, highlighting color should be stored (it will be required later, during painting). This requires a container storing the list of cells that are highlighted with certain color at certain time.
- When highlighting begins, a cell of corresponding color should be placed into this container with information of required highlighting time.
- Call Control.Invalidate(Rectangle) method for this cell. After that, Windows will generate a WM_PAINT message. Previously stored color should be used for the painting process.
- When highlighting time expires, Control.Invalidate(Rectangle) method should be called again to return the cell to original state. A programmer should also store information of highlighting time for each cell and create a timer that calls cell repainting on timeout.
- When multiple cells are highlighted simultaneously, the above timer should be shared between different cells that are currently highlighted. Shared use of timer is required to enable the most efficient use of computer resources as Windows OS supports a limited number of timers. A programmer has to enable continuous modification of timeout value since different cells have different time of highlighting expiration.
- A programmer should also consider that a new request for highlighting of a cell with the same or different color may arrive for already highlighted cell. Therefore, this information has to be processed, while timeout and highlighting color have to be updated for the affected cell.
- To save memory, container should be timely cleared of cells that are no longer highlighted.
- It is also necessary to consider that a data row can be filtered, sorted or removed from the grid. Since this may happen when cells are highlighted, it is necessary to handle such situations or the application may crash.
- For performance and CPU usage optimization, the highlighting system should work only with visible cells. If a user starts scrolling data vertically or horizontally, the program should track previously unseen cells showing in the visible area, determine remaining time of highlighting and call Control.Invalidate(Rectangle) method to highlight them as necessary.
- There are also other issues that should be taken into account to improve display quality, performance and memory consumption. E.g., if a grid highlights cells with some rows selected, highlighting and selection colors should be mixed for a better perception.
We can see that data highlighting system in an application is fairly complicated, and it is not always possible to meet all requirements due to lack of time or experience in programming for Windows.
One of distinctive .Net Grid features is an integrated grid cell highlighting system that supports specified color for the specified period of time. This system implements all the above actions including control of timers and containers that store colors and timeout values for highlighted cells. The grid timely clears containers of unused data and on highlighting timeout. This system also calculates cell highlighting colors mixing them with colors of odd/even rows and with selection and focus colors.
All complex details of highlighting management is hidden inside the grid, while a programmer gets a simple API to control cell highlighting with specified color for specified period of time:
Row row = ...;
Cell cell = row["Price"];
cell.Highlight(TimeSpan.FromMilliseconds(1000), Color.Green);
cell.Highlight(TimeSpan.FromMilliseconds(500), Color.Green, Color.Red);
This approach enables simultaneous highlighting of multiple cells including cells outside visible area of the grid.
Cell highlighting and INotifyPropertyChanged
The grid supports automation of cell highlighting on notifications from data objects that implement INotifyPropertyChanged interface. Highlighting attributes such as colors, time interval and highlighting type are set with Grid.Highlighting property. On notification, the grid synchronizes call with GUI thread if required and then it calls Cell.Highlight() with parameters taken from settings. Grid.RowUpdated event is the best way to control highlighting color and time. This event occurs on every notification from an object implementing INotifyPropertyChanged interface after synchronization with the main thread (if required). A Row containing the data object and IDataField with information of changed property are sent as arguments for this event. It is possible to add custom code to this event handler enabling highlighting of one or more cells with defined parameters.
grid.Highlighting.Color = Color.Gold;
grid.Highlighting.Interval = TimeSpan.FromSeconds(2);
grid.Enabled = true;
grid.Highlighting.Fading = false;
grid.RowUpdated += delegate(object sender, GridRowUpdateEventArgs e)
{
if(e.DataField.Id == "Price")
{
Share share = (Share) e.Row.DataObject;
Color color = share.Price > share.PrevPrice ? Color.Green : Color.Red;
e.Row["Price"].Highlight(TimeSpan.FromMilliseconds(1000), color);
e.Row["OtherField"].Highlight(TimeSpan.FromMilliseconds(1000), Color.Orange);
}
};
Cell highlighting is a continuous process. Cells can be repainted not just twice (before and after highlighting) but many more times within the specified time interval. This can be used to implement fading effect by multiple redrawing of cell background with changing transparency factor. When cells are redrawn, a programmer can always see how much time remains till the end of highlighting.
grid.PaintCell += delegate(object sender, PaintCellEventArgs e)
{
if(e.Cell.Column != null && e.Cell.Column.Id == "Price")
{
TimeSpan remainingTime = e.Cell.RemainingHighlightTime;
}
};
Highlighting control system enables efficient control of colors of different elements, mixing colors if necessary. E.g., it supports selected rows with highlighted cells. To enable this effect, the grid supports semi-transparent mode controlled by alpha factor set for selection and highlighting color.
grid.Selection.Color = Color.FromArgb(50, Color.Blue);
grid.RowUpdated += delegate(object sender, GridRowUpdateEventArgs e)
{
if(e.DataField.Id == "Price")
{
Share share = (Share) e.Row.DataObject;
Color color = share.Price > share.PrevPrice ? Color.Green : Color.Red;
color = Color.FromArgb(80, color);
e.Row["Price"].Highlight(TimeSpan.FromMilliseconds(1000), color);
}
};