I have an UltraWinGrid that gets loaded with data every time the user clicks on a refresh button. The new data is loaded into the UltraWinGrid by setting the DataSorce member to a new DataTable each time.
The grid is set up to allow the user to group the columns, sort on columns, or filter data using any of the columns. I need to preserve the grouping, sorting, and filtering. I have succeeded at doing that using the following methods:
Private sortIndicator As List(Of Infragistics.Win.UltraWinGrid.SortIndicator) Private filterConditions As List(Of Infragistics.Win.UltraWinGrid.FilterConditionsCollection) Private isGroupByColumn As List(Of Boolean)
Private Sub GetFlatColumnSortOrder()
Dim columnCount As Integer = grdServer.DisplayLayout.Bands(0).Columns.Count If (columnCount > 0) Then sortIndicator = New List(Of SortIndicator)(columnCount) filterConditions = New List(Of Infragistics.Win.UltraWinGrid.FilterConditionsCollection) isGroupByColumn = New List(Of Boolean) For index As Integer = 0 To columnCount - 1 sortIndicator.Add(grdServer.DisplayLayout.Bands(0).Columns(index).SortIndicator) Dim columnFilterConditions As Infragistics.Win.UltraWinGrid.FilterConditionsCollection = grdServer.DisplayLayout.Bands(0).ColumnFilters(index).FilterConditions filterConditions.Add(columnFilterConditions) isGroupByColumn.Add(grdServer.DisplayLayout.Bands(0).Columns(index).IsGroupByColumn) Next index End If End Sub
Private Sub SetFlatColumnSortOrder() If (sortIndicator IsNot Nothing) Then Dim columnCount As Integer = grdServer.DisplayLayout.Bands(0).Columns.Count For index As Integer = 0 To columnCount - 1 If (isGroupByColumn(index)) Then Dim descending As Boolean = False If (sortIndicator(index) = Infragistics.Win.UltraWinGrid.SortIndicator.Descending) Then descending = True End If grdServer.DisplayLayout.Bands(0).SortedColumns.Add(grdServer.DisplayLayout.Bands(0).Columns(index), descending, True) End If grdServer.DisplayLayout.Bands(0).Columns(index).SortIndicator = sortIndicator(index) grdServer.DisplayLayout.Bands(0).ColumnFilters(index).ClearFilterConditions() For Each fc As FilterCondition In filterConditions(index) grdServer.DisplayLayout.Bands(0).ColumnFilters(index).FilterConditions.Add(fc) Next Next (index) grdServer.DisplayLayout.Bands(0).Groups.Clear() End If End Sub
GetFlatColumnSortOrder() gets called before the DataSource is set and SetFlatColumnSortOrder gets called after the DataSource is set.
Everything works fine except that the current state of the groups (whether or not they are open or closed in not being preserved. If groups are set up by the user and the user has opened them, then after the Refresh button is pressed, the columns to be grouped appear in the group box and all filters and column sorting orders are correctly preserved, but all the groups are closed (so the user has to click on the + signs in the tree to reopen the ones he wants to be opened.
How do I save and restore the status (open/closed) of the groups?
Thanks,
Andy
Hello Andy,
When you resting the data source of UltraGrid, this action also reset the layout of the grid. SO if you want to preserve the layour you could use Save()/SaveAsXML() methods to save current layout and Load()/LoadFromXML() methods to restore the layout (I suggest you to use this overloads that takes as second parameter ProperyCategory):
http://help.infragistics.com/Help/Doc/WinForms/2012.2/CLR4.0/html/Infragistics4.Win.UltraWinGrid.v12.2~Infragistics.Win.UltraWinGrid.UltraGridLayout~Save.html
http://help.infragistics.com/Help/Doc/WinForms/2012.2/CLR4.0/html/Infragistics4.Win.UltraWinGrid.v12.2~Infragistics.Win.UltraWinGrid.UltraGridLayout~SaveAsXml.html
http://help.infragistics.com/Help/Doc/WinForms/2012.2/CLR4.0/html/Infragistics4.Win.UltraWinGrid.v12.2~Infragistics.Win.UltraWinGrid.UltraGridLayout~Load.html
http://help.infragistics.com/Help/Doc/WinForms/2012.2/CLR4.0/html/Infragistics4.Win.UltraWinGrid.v12.2~Infragistics.Win.UltraWinGrid.UltraGridLayout~LoadFromXml.html
preserving the layout will not preserves row states (in other words this will not save expansion state of your groups). So you should manually iterate trough your groups and to populate collection with the expanded one before resetting data source and after you recover the layout to expand those groups that are in your collection.
Please let me know if you have any further questions.
I find when I query for the groups (which the user set up using the grouping box, the grid indicates there aren't any groups. I tried something like
grdServer.DisplayLayout.Bands(0).Groups (and there weren't any Groups defined)
I believe I was using the Groups property on the band to get this. The only way I could even discover anything about the user defined group was by querying the each Column by using the following code:
grdServer.DisplayLayout.Bands(0).Columns(index).IsGroupByColumn
I didn't see any means to get the opened/closed state of the group. How can I do that.
(My grid is getting loaded with data from a single table into Band(0)).
The Groups property on the band refers to groups of columns. OutlookGroupBy, which groups the rows, is completely different and unrelated to that.
The Groups you are talking about here are rows - or, more specifically, GroupByRows.
So if you want to loop through the groups and determine which are expanded, you would loop through the grid.Rows collection and examine the Expanded property on the grid. You may also want to cast the UltraGridRow into an UltraGridGroupByRow so that you can access the row's Value and/or column for information on the grouping.
Sorry, but I don't quite understand. I have a number of columns, for example user id, session id, program id, and program name.
We allow the users to drag columns headers into the group by box so group the rows. There is a refresh button on the screen to get an updated list of sessions.
Every time the button is pressed the list of rows loaded into the grid can be very different, but the users want the groups they set up to be preserved and the expansion of those groups to be preserved. (We also allow sorting and filtering on all the columns).
The code above will save and restore the sorting, filtering, and columns that have been chosen on which to group, but I still don't understand how to save and restore the state (open or closed of the groups). I can iterate through the rows and get the values for the columns that the user has set up for grouping and build a collection of the combinations of those values and then for each one store the IsExpanded value. That seems like more work than I would expect to be necessary.
I suspect that I don't have the correct mental model of how this aspect of the grid works. Is there some collection that I can access which holds all the groups which the rows are divided into along with the values on which the group corresponds to? I was looking for some property on the band or on the row collection object,
Thanks for you great tech support. I appreciate how you guys respond so quickly to my questions.
Hi Andy,
If you are losing the groupings, then you are probably setting the grid's DataSource or calling the SetDataBinding method. So you are attaching to a new data source.
In such a case, keeping the same groups expanded is not really possible, because the groups are dependent on the data, and you are applying a new set of Data to the grid. The old data isn't there any more and there's new data in it's place and the grid has no way of associating the old data with the new data.
The only way this could work is for you to handle it yourself. That means looping through every row in the grid (recursively if there is more than one level of grouping) and then recording the expanded state of each GroupByRow, based on the Value. Then you would have to loop through every row again after you changed the data source and examine each row, see if a matching Value exists in the recorded information and expand that row, as needed.
If you are looking for a simpler solution, then I'm afraid there isn't one.
Thanks Mike.
I think I see how I can do this. Only about 10% of the rows should be different with each refresh, so if I have a way to uniquely identify the row's group, I can save that it's state (expanded/closed). Is there a good property to use to identify the row group?
It may work out to be easier and faster for me to add a second grid, so I can simply modify the data in my dataset and not ever change the data source, instead of resetting the data source each time.
My guess is that the active GroupByRow is not highlighted at all. But when you click on the row, it's getting selected and that's the highlight you are seeing. So in addition to the setting the ActiveRow, you probably just need to set the Selected property on the row to true.
Thanks Mike I got it to work, so the open groups are opened (if they still exist) when the data is refreshed.
Now I am trying to set the active row, so that row is highlighted.
It works fine for a row that contains data, but it doesn't completely work for a header row. The proper header row is set as active, but the row is not being highlighted by the grid. (In the case of a data row, the active row is highlighted).
What do I have to do to get the active header row to be highlighted?
Well... presumably you need two pieces of information to identify the row. The first is the GroupByColumn that the row belongs to. The second is the Value of that row.
You can get both of these very easily. Cast the row into an UltraGridGroupByRow and then you can access the Value and Column property.