I am working on an UltraWinGrid and want to be able to export it to Excel and print it. If I use the normal sort, filter, or group by features, the export and print both work as expected. However, on one of my columns, I have implemented a custom sort and custom filter. If I implement the custom filter, both the exported Excel document and the pdf printed (a pdf printer is default for development) print the column headers, but there is no other information regardless of the filter applied. Applying a custom sort and then exporting or printing works fine.
I am using Infragistics v 6.3.20063.53 (upgrading this tool is not an option for us at the moment as we just did a major upgrade on some other aspects of the project) in a VS2005 project.
Has anyone else come across this issue? If so, are there any workarounds?
Hi,
So by "custom sort", I assume you mean a SortComparer on one or more columns in the grid.
And by "custom filter",I assume you mean a class derived from FilterCondition.
Is that correct?
When you export or print the grid, the grid's Layout gets cloned. So... if the custom classes you are using for the SortComparer or FilterCondition are not serialiable (or not serialized properly), then they might not get copied into the cloned layout.
In fact, I am pretty sure that the grid does not attempt to clone the SortComparer, since it's an Interface that you could implement on any object. For example, if you implement IComparer on the Form and used that for the SortComparer of a column, it would be horrendously inefficient for the grid to clone the entire form. And not only would it be inefficient, it would cause an infinite loop, since the form contains the grid.
You seem to indicate that sorting is working, though, and that makes sense, since the grid has access to the oriignal layout in order to get the rows in the right order.
If it's just filtering that doesn't work, my guess is that you are deriving from FilterCondition, but your FilterCondition class has some extra properties that you added that are not getting serialized and so the filter is being applied as though it were using the default settings. If that is the case, then the solution would be to implement run-time serialization on your FilterCondition class.
But that's just a wild guess at this point without more information.
Mike Saltzman"]So by "custom sort", I assume you mean a SortComparer on one or more columns in the grid.
That's correct. The custom sort is done on one column in my grid.
Mike Saltzman"]And by "custom filter",I assume you mean a class derived from FilterCondition.
What I've done here is change the filter list - I removed the default Custom, Blanks, and NonBlanks items and replaced the default item values (the column contains images, so I was just getting a bunch of System.Drawing.Bitmap items) with friendly names. I changed this with the BeforeRowFilterDropDown event.
As for the actual filtering, I filter on the AfterRowFilterChanged event. Since the column with the images doesn't give me information on the actual values of the cells, I have created a hidden column containing the values I need. In short, there are two columns with the same information - one as images and one as text. On the AfterRowFilterChanged event, I take the filter from the image column (using FilterConditions) and then apply it to the text column. The result of this is a correctlyfiltered grid. I haven't created a special FilterCondition class.
I hope that helps clarify things a bit more.
If, as you have suggested, extra properties aren't being serialized, shouldn't the entire grid show up because it would ignore any filtering?
Thanks for your help!
Okay, it's hard to say what's going on there. So you are populating the filter dropdown yourself with just images? So you are probably using BeforeRowFilterDropDownPopulate for that.
So what exactly are you doing in AfterRowFilterChanged? It sounds like you are changing the filters that get saved somehow.
I guess the real question is - what is actually in the FilterConditions collection of the column? Whatever it is, it seems like the grid is unable to copy it over into the print/export layout. So you might have to handle the InitializePrint event or the BeginExport event and manually copy the filters from the real grid.DisplayLayout into the Layout that is passed into the event.
Hi Mike
Sorry for the delayed reply - I didn't have a chance to look at this for the last couple of days.
Mike Saltzman"]So you are populating the filter dropdown yourself with just images? So you are probably using BeforeRowFilterDropDownPopulate for that.
I am indeed using the BeforeRowFilterDropDownPopulate event for the dropdown.There are only 6 possible values for the column, so I just hardcoded everything. Here is the code in the BeforeRowFilterDropDownPopulateEvent:
if (e.Column.Equals(grid.DisplayLayout.Bands[0].Columns["Status"])) { for (int i = e.ValueList.ValueListItems.Count - 1; i >= 0; i--) { if (e.ValueList.ValueListItems[i].DisplayText.Equals("(Custom)") || e.ValueList.ValueListItems[i].DisplayText.Equals("(Blanks)") || e.ValueList.ValueListItems[i].DisplayText.Equals("(NonBlanks)") || e.ValueList.ValueListItems[i].DisplayText.Equals("System.Drawing.Bitmap (System.Drawing.Bitmap)") || e.ValueList.ValueListItems[i].DisplayText.Equals("System.Drawing.Bitmap")) { e.ValueList.ValueListItems.RemoveAt(i); } } //allow filter by each value e.ValueList.ValueListItems.Insert(1, new FilterCondition(e.Column, FilterComparisionOperator.Equals, "Filter1"), "Filter1"); e.ValueList.ValueListItems.Insert(2, new FilterCondition(e.Column, FilterComparisionOperator.Equals, "Filter2"), "Filter2"); e.ValueList.ValueListItems.Insert(3, new FilterCondition(e.Column, FilterComparisionOperator.Equals, "Filter3"), "Filter3"); e.ValueList.ValueListItems.Insert(4, new FilterCondition(e.Column, FilterComparisionOperator.Equals, "Filter4"), "Filter4"); e.ValueList.ValueListItems.Insert(5, new FilterCondition(e.Column, FilterComparisionOperator.Equals, "Search5"), "Search5"); e.ValueList.ValueListItems.Insert(6, new FilterCondition(e.Column, FilterComparisionOperator.Equals, "Search6"), "Search6"); }
Mike Saltzman"]So what exactly are you doing in AfterRowFilterChanged? It sounds like you are changing the filters that get saved somehow.
Since the Status column (from above) contains images, it couldn't be sorted, so I created a hidden column called "Status Text," which is essentially the same information shown in the Status column except as words instead of images. I applied the filter to it instead in the AfterRowFilterChanged event (code below):
//filter cannot be applied to Status column because images are unfilterable, so filter must be done on Status Text column if (e.Column == grid.DisplayLayout.Bands[0].Columns["Status"]) { //get the filter condition chosen from the Status column FilterConditionsCollection f = e.NewColumnFilter.FilterConditions; //clear all filters on Status Text column and then add filter from Status column grid.DisplayLayout.Bands[0].ColumnFilters["StatusText"].ClearFilterConditions(); for (int i = 0; i < f.Count; i++) { grid.DisplayLayout.Bands[0].ColumnFilters["StatusText"].FilterConditions.Add(f[i]); } }
The grid still had the correct column filters when I checked (right before the print), but the DisplayLayout wasn't right. I made the change as you suggested, but I am still having the same issue with the print. As for the export to Excel, I'm working on that area of the application right now and it isn't fully functional yet, so I can't verify the behavior there at the moment.
Looks like I managed to figure it out :)
When I was applying the filter on the Status column to the Status Text column, I was leaving the filter criteria on the Status column. As soon as I cleared the Status filter (so the Status Text filter would be applied, but the Status filter was cleared), everything started exporting fine.
Thanks for all of your help Mike!