Hi,
I have a confusion over the timing of populating an UltraDataSource.
What is the exact purpose or extra that a UltraDataSource provides over the other collections like DataSets, DataTables or ValueLists? Simply stating, why would anyone need an UltraDataSource, when one can simply bind these other objects to the ultragrid?
What is the difference between populating a ultradatasource in a custom method call and in a InitializeDataRowCollection? What is the difference between populating the ultradatasource in a InitializeDataRowCollection versus IntializeDataRow?
What do the ISupportInitialize calls for BeginInit and EndInit implemented by UltraDataSource do in specific?
What is the most efficient way to populate an ultradatasource? Does Ultradatasource allow being accessed from a back ground thread?
Thanks,
Bhushan.
Hi Bushan,
There are a number of different situations in which you might want to use an UltraDataSource.
If you are using a data source like SQL Server, then a DataSet/DataTable is designed to allow you to retrieve and update your data to the back end.
But maybe you have a very simple app where you need a grid to display some local data to the user and don't want to set up a complex DataSet/DataTable. You could use an UltraDataSource in this case and define the data right in code.
You could also do this with more complex data in a case where you don't need relational data. For example, if you have data where the parent are child rows are simply hard-coded and don't change, as opposed to relational data where the parent and child data are based on a value within the data. This also make the UltraDataSource a little faster when working with hierarchical data, since it doesn't have to calculate the relationships.
Bhushan Inamdar said:What is the difference between populating a ultradatasource in a custom method call and in a InitializeDataRowCollection? What is the difference between populating the ultradatasource in a InitializeDataRowCollection versus IntializeDataRow?
These events are for loading data on-demand. This is for efficiency and performance where you have a large set of data to show and you don't want to load it all at once. There are samples included with the suite called the "Virtual Mode sample" which demonstrates using the UltraDataSource to show 1 million rows in an UltraWinGrid in an efficient way without loading all of the data up front.
Bhushan Inamdar said:What do the ISupportInitialize calls for BeginInit and EndInit implemented by UltraDataSource do in specific?
ISupportInitialize is for design-time serialization and deserialization. It''s not really something you need to worry about, it's all handled by the designer.
Bhushan Inamdar said:What is the most efficient way to populate an ultradatasource? Does Ultradatasource allow being accessed from a back ground thread?
Using threading with DataBinding is generally not a good idea. When you use multiple threads, you need to marshal the communucation between those threads and in the case of data binding, you are not in control of that communication. So while it might, in theory, be possible to populate an UltraDataSource on a separate thread, you cannot do it while it's bound to a control in the UI, which would probably defeat the purpose of using another thread, so there wouldn't be much point in it.
The most efficient way depends a lot on what your requirements are and what your app needs to do. As I mentioned you can use load-on-demand if you can efficiently load your data from wherever it's stored a piece at a time in an efficient way. Generally speaking, I think the most common use case is to just populate the data up front - which will work fine as long as your data set is of a reasonable size.
Hi Mike,
Thanks for the detailed response to my rather vague queries. The reason for me to ask such queries was to get a general understanding of whether or not there is a general rule of thumb working with the infragistics controls to take care of the minimalistic performance related gotchas. For instance, quite often we see in winforms applications, that the how events get triggered when not needed and unnecessary repetition of loading of the data on the form appears. Let us say Tab changed event. Firstly, in the form load we often load the default data and then set the tab index to a tab page. Now there is some code in the tab changed event, that is exactly similar to the code that we wrote in the form load. So to avoid this, I usually call the Tab Changed event handler in between the statements to unsubscribe and subscribe to the tab changed event. This saves the coding effort as well as prevents the same code getting executed a number of times. Also, in the case of data binding, when the data source is assigned to a winforms gridview, then the Datasourcechanged and related events are fired. If there are handlers attached to these events, they would get executed multiple times. In complex winforms, a lot of exceptions can be attributed to these kind of scenarios. I usually analyze the winform and find out the sequence of firing of events and then code accordingly.
Coming to our Infragistics case. I know that there would be some issues in marshalling if I use separate threads to populate the infragistics ultradatasource. But nonetheless, people have used separate threads to fetch the data in the background, and then populate the data on the main thread using the Control.InvokeRequired property and Control.Invoke methods. Also, a proper way to use multi threading is to use auto / manual reset events and wait handles for signalling. Well, that is for the case where we are dealing with substantial volume of data. In my case, I have been able achieve without multi threading as it was fairly simple as far as data is concerned. The data rows in a grid would not exceed a few thousands and hence I use preloaded option instead of LoadonDemand.
As of now, I do not have any performance issues. But I would love to avoid repetitive coding. The thing is, there are about 15 ultra grids with similar columns, column styles, cell formatting, grid borders, location, etc. However, the UI for a single grid is much comples and I am using IntiailizeRow event to do custom value based formatting. Also, I have applied conditional appearances to column headers. Also, I am using creation filter for allowing column expand and collapse feature. I am also currently trying to implement custom expand/collapse indicators for the rows. For that I am not using child bands and child rows, but simple indentation and I intend to insert a (+/-) image in the Left most column using either creation filter or a draw filter (...if that is possible). I would like you to comment upon this as to if it is possible to handle this is feature along with the existing column expand and collapse indicators. For columns, I am using HeaderUIElement from the Parent in the AfterCreateChildElement(...) method and intend to extract CellUIElement for the 0th row. Or is there a better way using a drawfilter? So going back to what I would like to have is to know if there is an UltraGrid extensibility sample application for winforms, that allows me to implement abstract and virtual methods that have the functionality common to all the grids. I had started trying this out, but gave up soon as I did not find any resources. Further, I wanted to use that extended control, and implement an MVC architecture to invoke the controller from the said 15 places to invoke the respective grids. But, sadly, I have ended up repeating the code in few places. That is not bad altogether from the performance perspective, but it is not good from the maintenance perspective. Request you to comment upon this as well.
Going back to the performance related tips, I would like to know, as to what know if in the Infragistics UltraGrid or UltraDataSource, is there a need to make a call to call an Update(), Invalidate(), Refresh() calls and what are the scenarios to call them? Also, there are 2 overloads of the UltraDataSource constructor, one is default parameter less constructor and the other takes in the Container type as a parameter to which usually the parent container is passed as (this.Container). What is purpose of passing it and how shall it be sued?
Although not very critical for my on going implementation, it would be great if I could get some answers to these long pending questions...