The main idea of the grid is separation of business logic from its presentation. Business logic is your C++ objects with their polymorphic behavior that can be inserted directly in the grid. Your business objects may be presented in different ways with different formats in one or more grids. You can add these objects by calling
Add() function of the grid, so that afterwards the grid updates, sorts, highlights and filters the objects itself. A programmer doesn't have to carry out complicated algorithms of data updating or sorting any more.
Polymorphous data behavior
Automatic text updating and highlighting
Automatic sorting (multiple sorting)
Automatic filtration
Shortened time of application development
Multithreading
Productivity
Hierarchical data organization
Rows and columns with different height and width
Fixed rows and columns. Hierarchical data in fixed rows
Elements selection. Selecting elements without destroying background
Icons, bitmaps
Data presentation. Inserting one element into different grids
Customization of drawing
Built-in controls and their positioning in the grid
Tooltips
Copy & paste
Drag & drop
Navigation
Printing
Serialization with versions support
The main grid feature is capability to insert an object of practically any class in the grid. The grid uses binding mechanism that permits to call class methods. This means that class methods correspond to grid columns, and objects correspond to rows. Intersection of line and column is a value returned by C++ object. This approach is more useful than binding to object container. Object container restricts business data structure, its placement in application etc. It is too difficult to design a hierarchy by using multiple containers. With our grid, you can store your objects anywhere and build any hierarchy. You can clearly and easily determine where your C++ objects are placed in the grid. You can do practically any manipulation in the grid by using your objects. For example, when you call
grid.Select(your object) the grid will select the right line. You do not have to find the row's index that corresponds to the business data to select it.
As described above, the grid cell presents a value returned by the object. The value is transformed into a string through a format declared with the class. We propose a mechanism to notify the grid when you change values inside your C++ object. Once you have updated your object, the modifications will be reflected anywhere in each grid, where the object was inserted. The right cell will be automatically highlighted. You do not need to create timers to highlight your data. With the grid, you don’t have to do this routine. Note that all notifications are thread-safe and implemented without blocking the calling thread. So, there is no dead-lock risk.
If you implement the notification mechanism (this is very easy), you will benefit from automatic sorting of dynamically changing data in each grid where your business data was inserted. Various grids may have different sorting rules and may use any hierarchy. No need to worry - each grid will sort your data properly.
Moreover, if you implement the notification mechanism the grid will filter (show or hide) dynamically updating data. You only have to define the filter rules in
Dapfor::GUI::IGridFilter interface. There is only one function which returns a boolean that indicates whether your C++ object can be visible or not. So, you can update your object and each grid will filter the object according to the filter rules. You do not need to know where your object was inserted. Note that this also works in the hierarchical grids.
As you see, the grid implements many useful features that will help you release your project in a short period with very high quality. There are no compromises. We paid attention to a lot of details and we put all our skills to develop this component.
The grid was designed to work in a heavy multi-threaded environment. Practically all functions are thread-safe. They use both synchronous and asynchronous mechanisms with or without blocking the calling thread. Inserting, removing, getting etc. work with blocking the calling thread. Any data is updated through asynchronous mechanism. Thread calling does not wait for the end of updating operation. Much of updating may take place at the same time. This excludes dead-lock between GUI and non-GUI threads.
To display information in cells, the grid needs to retrieve values from your business objects. There are two thread-safe modes to do it:
- Dapfor::GUI::CPreferences::DirectCall: The grid asks for values in GUI thread each time it needs to paint cells or scroll lines. It is up to you to protect your business data (the grid is thread-safe). This mode is more productive than the other one. It has low CPU and memory load.
- Dapfor::GUI::CPreferences::MemoryBuffer: At each update the grid copies values, formats them in the calling thread and then no longer calls methods of your objects. The grid gets all information from the local cache. This mode is less productive but more secure.
The grid combines real and virtual operating modes. The data is inserted into the grid in real mode and data is highlighted, sorted and filtered in virtual mode. Taking advantage of both modes, the grid ensures a very high level of productivity. The CPU and memory load depends on the thread safety mode.
Dapfor::GUI::CPreferences::DirectCall is more productive as compared to
Dapfor::GUI::CPreferences::MemoryBuffer. Nevertheless, productivity of each mode is more than enough to deploy practically any application. The grid permits to insert more than 100000 elements per second, to do more than 50000 automatic data updates with their automatic highlighting and more than 5000 data updates per second with their automatic sorting, filtering and highlighting.
Initially, the grid was designed for hierarchical data presentation. The hierarchy is organized when elements are being inserted in the grid and can be easily changed later. You can insert objects of various classes into the same grid. This permits to construct any type of hierarchy. You can store your objects anywhere in the application. All above features are available both for flat and hierarchical grids...
Each column of the grid can have its own set of attributes that allow to present information in the most convenient way. You can assign width, text format, graphical format etc. for each column. The height of a row can also be defined individually.
The grid supports so called "frozen" rows and columns in the grid. While scrolling elements in the grid, such rows and columns always remain at their positions. To freeze columns, you only have to set their number. When freezing the rows, please remember that data can be hierarchical. When you 'expand/collapse' or 'filter', a number of grid rows in the fixed area may change. So "frozen area" is defined not by a row's absolute number but by the context where data objects are inserted. The grid supports two contexts: scrollable and fixed. As follows from its name, in the fixed context data cannot be scrolled and remain constantly visible.
You may use different color schemes for cells, columns and rows in the grid. When you select a line, important color information may become inaccessible. To avoid this, the grid uses alpha-blended operations to mix the selection color with that of the background. To select a lot of elements with the mouse, there is a user-friendly way to automatically scroll and select data. Scrolling speed changes as the distance between scrolling cursor and the grid client area increases.
The grid provides simple features to show pictures in cells. You can stretch icons or change them dynamically. It is really easy to implement changing cyclic icons by using highlighting features. In addition, you can set a background bitmap with a specified transparency coefficient.
The most powerful feature of the grid is capability to work with objects of arbitrary classes. As described above, the rows correspond to your business objects, and columns – to class functions. The grid cells show values returned by functions of these objects. Note that functions return only non-formatted typed values like long, double etc... The grid cannot show them directly in cells. To show values in cells, formats are used. They transform received values from business objects into strings and vice-versa. You can use the same set of formats in each grid, define it for each grid's header, or use individual formats just before painting. So, the same object can be presented in many ways even in the same grid.
The grid works in both real and virtual modes at the same time. The real mode allows you to insert objects into the grid while the virtual mode is used for data drawing. When data are being drawn, the grid provides all information about a business object, its placement and state, colors, fonts etc... Our developers have gone to great lengths to concentrate grid drawing at one place, and to take advantage of both modes; they have provided a surprisingly easy way to redefine and customize anything. The decision about font type and size, icon type, background color, highlighting and so on can be made at the time of drawing. When you have all the information about object's state, it is easy to take any decision. For instance, you do not need to find data placement to change color scheme. You will be asked by the grid when it needs the color information for painting. As a result, you can insert your business data into the grid and forget about it.
The grid provides very simple and useful positioning service for practically any MFC controls with navigation between them. In most cases, buttons, check boxes, and so on are not real controls but only their drawings. Basically, such 'controls' are supplied together with the grids and their number and functionality may be limited. Moreover such approach does not allow to use already existing solutions or third-party libraries. In case of real controls it is necessary to handle their location and size according to a number of elements in the grid, scrollbars' positions and also to manage their visibility (in case of filtration, expand/collapse and row deleting). This is not a trivial task and some difficulties may appear during deployment process. We offer the solution that permits you to attach practically any MFC control to any cell and the grid will handle positioning and visibility of the controls.
A tooltip is designed to enhance application functionality e.g., when information that must be provided to the user cannot be displayed in full. The grid provides several solutions:
- A tooltip that shows information in a small popup window as plain or html text in the popup browser.
- You can fully customize the tooltip and display some shapes or other MFC controls.
- Embedded tooltip. If a part of text in a cell becomes invisible, the remaining text is automatically shown in the tooltip above the cell with the same font.
Copy & paste allows you to move data inside one grid, between various grids or between different applications. The grid supports export of data to such applications as Excel and Word. In addition to standard clipboard formats,
GUI library has new ones that support hierarchical information and also enable to move data between different applications with data serialization, where possible. A programmer can customize the copy & paste mechanism any moment.
The grid provides default Drag & drop implementation. It is possible to move selected lines inside one grid, between grids or between different applications. Moreover, a programmer can customize drag & drop behavior for his purposes any moment. To indicate a dropping place the grid illuminates the lines between which data will be inserted. However in case of hierarchical data it is not enough because the level of hierarchy remains unknown. Our grid enables to indicate this hierarchical level that allows to clearly specify how a user wants to insert data into the desirable position.
Working with two data contexts (fixed & scrollable), the grid handles the navigation and harmoniously processes data selection, line scrolling and focusing. The programmer can define, contexts in which navigation takes place, or completely redefine it. In case of Edit in Place controls, the grid handles navigation (Tab, Shift Tab, Key Left, Key Right, etc.). This allows to activate the next control by using the keyboard.
The grid allows to print out its content and supports a 'print preview' option. Various scaling levels and choosing between portrait and landscape modes of images will satisfy all clients' demands.
Serialization in
CArchive is a useful grid feature. A position, color of columns, colors, user's preferences, and so on are serialized. The grid is projected in such a way that new grid versions will be compatible with the archives made in previous ones.