This is a migrated thread and some comments may be shown as answers.

[Solved] Transferring Filters from One RadGridView to Another

4 Answers 359 Views
GridView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Corey
Top achievements
Rank 2
Corey asked on 09 May 2013, 10:32 PM
I have a RadGridView that resembles the one below.  The grid allows for pop-up filtering on each column.  We allow the user to modify rows within the grid and once they are done we rebuild the entire page (which involves destroying the previous grid and building a new one).  Currently, we transfer any filters and selected row information from the previous grid to the new grid via a custom variable that grabs the RadGridView's FilterDescriptors.

However, when we programmatically add these filters to the newly build grid during the Loaded event of the RadGridView (a la RadGridView.FilterDescriptors.Add(filter);), the new grid correctly filters on the designated columns in the right way, but it does so exclusively.  Using the example grid below, if I were to filter the grid on Route ID = 003 and then modify that row (triggering the building of a new grid on the page), the new grid would only display the 003 row (even though the Items attribute contains the other two rows) with no way of accessing the other rows and no filter on the grid even acknowledged.  Furthermore, if I try to filter on Route ID again, the only option for me to filter on is 003.  I've included some pictures to better explain my problem.

What I'm hoping to accomplish is to allow the building of the new grid as it currently does, but to transfer the filters as they were from the previous grid.  I don't want the new grid to be locked into a hard filter on said filters.  Is this possible?


TripSet ID          Date          Route ID
010                     4/9/13         001
010                     4/9/13         002
010                     4/9/13         003

4 Answers, 1 is accepted

Sort by
0
Pavel Pavlov
Telerik team
answered on 10 May 2013, 06:31 AM
Hi,

May you paste the code that takes care of storing/restoring the filter descriptors. Also it would be nice to know what is the source collection type.

I will have a look and see what went wrong.

Greetings,
Pavel Pavlov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Corey
Top achievements
Rank 2
answered on 10 May 2013, 01:45 PM
Here is most of the code used to build the RadGridView (both the initial one and the new one).
public RadGridView BuildGrid(DataTable dataTable, IEnumerable<WspViewRow> gridRows)
{
   RadGridView radGrid = new RadGridView();
   
   radGrid.Loaded += new RoutedEventHandler(_radGrid_Loaded);
   
   BuildColumns(radGrid, dataTable);
   BuildRows(radGrid, dataTable, gridRows);
   
   radGrid.ItemsSource = dataTable;
   
   return radGrid;
}
BuildColumns creates custom GridViewDataColumns that we add to the RadGridView.  BuildRows binds the data accordingly and creates DataRows that we add to our DataTable ItemsSource.

Here is the method that saves the previous grid's FilterDescriptions.  It saves some other things, but only the filters are worth noting at this point.
protected override void SaveRunTimeData()
{
   _runTimeData = new RunTimeData()
   {
      GridFilters = RadGridView.FilterDescriptors
   };
}

Lastly, here is our RadGridView.Loaded event handler that sets any filters from the previous grid.
void _radGrid_Loaded(object sender, RoutedEventArgs e)
{
   if (_runTimeData != null)
   {
      foreach (ColumnFilterDescriptor filter in _runTimeData.GridFilters)
         RadGridView.FilterDescriptors.Add(filter);
 
      _runTimeData = null;
   }
}
0
Accepted
Pavel Pavlov
Telerik team
answered on 10 May 2013, 02:00 PM
Hello,
I have I have consulted with the team on your problem and here is the output :

The column filter descriptors hold a reference to a column . When you recreate RadGridView brand new columns appear which are not the same instances with the old ones.

The Filter descriptors still hold the old columns thus the erroneous behavior.

The solution would be to create new filter descriptors based on the values in the old ones , rather than reusing them.

You may see some working code in this online example. Check the code in the cs files for more info .

All the best,
Pavel Pavlov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Daniel
Top achievements
Rank 1
Iron
commented on 02 Jul 2024, 10:09 AM

Unfortunately, I cannot open the example. The following code transfers the filter function itself, but when the user opens the settings via the column header, he only see them in an empty initial state, even though filters are applied. What is missing here?
rgvTo.FilterDescriptors.Clear();
foreach(var fd in rgvFrom.FilterDescriptors)
{
	if(fd is MemberColumnFilterDescriptor mcfd)
	{
		var targetColumn = rgvTo.Columns[mcfd.Member];
		if(targetColumn != null)
		{
			var newDescriptor = new MemberColumnFilterDescriptor(targetColumn);
			newDescriptor.CopyFrom(mcfd);
			rgvTo.FilterDescriptors.Add(newDescriptor);
		}
	}
}

Martin Ivanov
Telerik team
commented on 03 Jul 2024, 11:10 AM

You can find the example linked by Pavel in the WPF Demos application under the name "GridView Serialization".

About your code, this doesn't work because the FilterDescriptors collection is not automatically synced with the ColumnFilterDescriptor of the column. The synchronization happens only in the opposite direction - ColumnFilterDescritpro --> FilterDescriptors collection.

To make this work you can copy the filter descriptor in the ColumnFilterDescriptor of the target column.

if(fd is MemberColumnFilterDescriptor mcfd)
{
	var targetColumn = rgvTo.Columns[mcfd.Member];
	if(targetColumn != null)
	{
		targetColumn.ColumnFilterDescriptor.CopyFrom(mcfd);
	}
}

Daniel
Top achievements
Rank 1
Iron
commented on 04 Jul 2024, 06:05 AM

Thank you, this helps.

But how can the various fields in the associated dialog be set for column filters, which are of the MemberColumnFilterDescriptor type?
In other words, which elements are checked, which two operators apply, which operator is used to link them, and which value should be used for the comparison. There are no explicit properties for this in the class.
Martin Ivanov
Telerik team
commented on 04 Jul 2024, 06:20 AM

The code snippet below shows what the CopyFrom method does. These are basically the properties which can be used to get and set the filter operators and values. The order in the code even matches the order in the UI of the FilteringControl. To get the distinct vaues, you can use the filter.DistinctFilter.DistinctValues property, which is not shown in the snippet.

 public static void CopyFrom(this IColumnFilterDescriptor target, IColumnFilterDescriptor source)
 {
     foreach (var dv in source.DistinctFilter.DistinctValues)
     {
         target.DistinctFilter.AddDistinctValue(dv);
     }

     target.FieldFilter.Filter1.Operator = source.FieldFilter.Filter1.Operator;
     target.FieldFilter.Filter1.Value = source.FieldFilter.Filter1.Value;
     target.FieldFilter.Filter1.IsCaseSensitive = source.FieldFilter.Filter1.IsCaseSensitive;

     target.FieldFilter.LogicalOperator = source.FieldFilter.LogicalOperator;
 			
     target.FieldFilter.Filter2.Operator = source.FieldFilter.Filter2.Operator;
     target.FieldFilter.Filter2.Value = source.FieldFilter.Filter2.Value;
     target.FieldFilter.Filter2.IsCaseSensitive = source.FieldFilter.Filter2.IsCaseSensitive;
 }

Daniel
Top achievements
Rank 1
Iron
commented on 04 Jul 2024, 06:30 AM

OK. Visual Studio is a bit crazy here. Because for MemberColumnFilterDescriptor, which is derived from ColumnFilterDescriptor and IColumnFilterScriptor and has the property FieldFilter etc., it does not display them.
Martin Ivanov
Telerik team
commented on 04 Jul 2024, 06:41 AM

Oh, yes. I forgot to mention this. Sorry about that.

The base class (ColumnFilterDescriptor) of the MemberColumnFilterDescriptor implements the IColumnFilterDescriptor interface explicitly, which makes the interface members hidden from the derived class. To access these you will need to cast the MemberColumnFilterDescriptor to IColumnFilterDescriptor.

var filterDescriptor = (IColumnFilterDescriptor)mcfd;

0
Corey
Top achievements
Rank 2
answered on 10 May 2013, 02:21 PM
Awesome.  Thanks Pavel.

That fixed it and it's working great now.
Tags
GridView
Asked by
Corey
Top achievements
Rank 2
Answers by
Pavel Pavlov
Telerik team
Corey
Top achievements
Rank 2
Share this question
or