Description:
I am looking for a grid control, and see most of the features that I desire in the XtraGrid. However, one feature that I do not see is virtual grid support - which displays more data than can readily be loaded into memory. Can you please tell me if this is a feature your grid control has?
Answer:
Virtual Load or Server mode is supported starting with XtraGrid v2007.1 via our IListServer interface. XPO implements this interface, so that you can easily enable Server mode in your grid if you bind it to the XPServerCollectionSource component. Please explore the ServerMode modules of the XtraGrid's GridMainDemo sample project. Also, starting with version 10.2, we have introduced the Instant FeedbackTM UI. Take a look at the following article:
Instant FeedbackTM UI
If you did not use XPO before, the Mapping XPO to an Existing DBarticle will help you create persistent objects for your database.
You can try to implement the IListServer interface yourself in your own data object. However, this is not a trivial task. Below is a brief description of IListServer.
C#public interface IListServer {
CriteriaOperator Filter { get; set; }
void ApplySort(ListSortDescriptionCollection sortInfo, int groupCount,
List<ListSourceSummaryItem> summaryInfo, List<ListSourceSummaryItem> totalSummaryInfo);
List<ListSourceGroupInfo> GetGroupInfo(ListSourceGroupInfo parentGroup);
object[] GetUniqueColumnValues(PropertyDescriptor descriptor, int maxCount, bool includeFilteredOut, bool roundDataTime);
Dictionary<object, object> GetTotalSummary();
object GetRowKey(int index);
object FindKeyByValue(PropertyDescriptor column, object value);
object FindKeyByBeginWith(PropertyDescriptor column, string value);
int GetRowIndexByKey(object key);
}
Filter is a grid filter which must be applied to data fetched from a database.
ApplySort is the key method. It is used to sort items in your data list. The sortInfo parameter lists the columns which participate in sorting. Since grouping is based on sorting, the first groupCount items in the sortInfo array identify group columns. summaryInfo and totalSummaryInfo parameters indicate which summaries must be calculated.
GetGroupInfo is also important. It must return sub-group rows for a given group when the grid is grouped against multiple columns.
GetUniqueColumnValues returns the values list for the column filter dropdown.
GetTotalSummary is used for summary calculation.
FindKeyByValue and FindKeyByBeginWith serve lookup columns and the auto-filter/auto-complete feature in the GridLookUpEdit.
From version 10.2 this interface is modified as follows:
C#public interface IListServer: IList {
void Apply(CriteriaOperator filterCriteria, ICollection<ServerModeOrderDescriptor> sortInfo, int groupCount, ICollection<ServerModeSummaryDescriptor> groupSummaryInfo, ICollection<ServerModeSummaryDescriptor> totalSummaryInfo);
List<ListSourceGroupInfo> GetGroupInfo(ListSourceGroupInfo parentGroup);
object[] GetUniqueColumnValues(CriteriaOperator expression, int maxCount, bool includeFilteredOut);
Dictionary<object, object> GetTotalSummary();
object GetRowKey(int index);
int GetRowIndexByKey(object key);
int FindIncremental(CriteriaOperator expression, string value, int startIndex, bool searchUp, bool ignoreStartRow, bool allowLoop);
int LocateByValue(CriteriaOperator expression, object value, int startIndex, bool searchUp);
IList GetAllFilteredAndSortedRows();
event EventHandler<ServerModeInconsistencyDetectedEventArgs> InconsistencyDetected;
event EventHandler<ServerModeExceptionThrownEventArgs> ExceptionThrown;
void Refresh();
}
To learn more, please review our implementation of IListServer in our source code, and a simple example attached to this article. We also advise that you think about using XPO in the data access layer of your project.
Older versions (before the 2007.1 release) don't have the Server Mode feature, sorry. Please keep in mind that the grid does not have an internal array into which it would load data; it fetches only those records, which need to be displayed within the GridControl's boundaries. Therefore, the dynamic loading feature should be implemented at the data object level. Sorry, we don't have a sample project for this article. It's up to you how you implement the virtual data list. We advise that you review the GridVirtualData module of the GridTutorials demo shipped with the XtraGrid. You will be able to implement the desired feature, if you extend the VirtualList class with a DataTable object, which is stored internally. DataTable should be dynamically populated. The IList.this[int index] property should look for a row in the DataTable object at the index. If DataTable.Rows.Count is less than the index, you should fetch another block of records from the database. You can use an overload of the DbDataAdapter.Fill method, which has a maxRecords parameter (e.g. use the SqlDataAdapter.Fill(DataSet, int, int, string) method).
Another solution is to utilize XPO's XPPageSelector component as the grid's DataSource. This solution works in all XPO versions. In this case, you could add the Next/Previous Page buttons to User Interface, which change the XPPageSelector.CurrentPage property when clicked. When XPPageSelector.CurrentPage is changed, a new "page" of records is loaded from the database and is displayed in the grid.
Actually, you can load about 100,000 records and the grid will still perform acceptably on a modern desktop system. The grid can group, sort, and filter such an amount of data relatively fast. However, if your task is to display 100,000 rows or a larger list to end-users, this may indicate an application design flaw: in most cases users don't really need so much data simultaneously. It's best to provide a user with a comprehensive set of pre-filters, so he or she can load the desired subset of data from the database. From our point of view, this feature (predefined filters) could give more value to your application than the virtual load when scrolling a long list of records.
See Also:
Server Mode
Upcoming XPO/XtraGrid feature: server-side mode
A992