we allow users of one of our applications to save custom views of the grid and this includes modifying the default filter operator (without necessarily requiring them to be filtering at the time). When they save the view I need to find the current state of the operator. I can see this in debug and have screwed around with Reflection to try and get to the value but thus far have not gotten what I neeed. I have to believe there is a simpler answer.
Hi Paul,
I'm a little confused about exactly what you are trying to get here. What is this object that we are looking at in the screen shot?
The default operator for every filter cell is set on the Override:
this.ultraGrid1.DisplayLayout.Override.FilterOperatorDefaultValue = FilterOperatorDefaultValue.Contains;
So that would be the filter operator used in every cell of the filter row if the user has not changed it by dropping down the operator list and choosing a different operator for that cell.
Is that what you need? Or are you saying that the user has dropped down the list and chosen an operator in a particular filter cell and you want to get that? I'm pretty sure that's not exposed anywhere publicly. And I'm not sure if it can be accessed via reflection. It would be pretty tricky.
Hi Mike. Thanks for your reply. For the grid columns we store defaults that a user absorbs the first time they access the application in the grid. An administrator has predefined a filter operator for each column so for example I might have a column name that they have specified contains for while on address they may have defined startswith. When the grid initially loads for the user we set the FilterOperatorDefaultValue as you show. However, since we allow the user to save personalized views including position, width, hidden, pinned, etc. along with sorts, filters and such, I had wanted to allow them to override the administrator settings for filter operator in their personalized view settings. I can make a change (without specifying an actual filter value) and when I iterate all column filters in the grid I can see the change made in the non-public properties of flt (below) but nowhere else. So based on your answer I assume this is a no go.
foreach (ColumnFilter flt in ultraGridACM.DisplayLayout.Bands[0].ColumnFilters) {
}
I was able to figure out how to get that member variable via reflection. I included that code here commented out. But I think you will be better off using the GetOperatorValue method on the FilterRow instead. It's also internal, but I got it via reflection, too. It think that's better because it goes through the same resolution process the grid uses.
I'm sure you know this, but just be aware that if you use reflection like this, this may be broken in a future release of the controls if we have to change something or make a bug fix here. It seems very unlikely to me, but it could happen. So do this at your own risk. :)
foreach (ColumnFilter flt in this.ultraGrid1.DisplayLayout.Bands[0].ColumnFilters) { FilterComparisionOperator filterComparisionOperator = FilterComparisionOperator.Equals; // This gets the filter operand from the GetOperatorValue method. // I think this is probably a better approach than using the member variable // since it goes through the resolution process that the grid actually uses. var grid = this.ultraGrid1; var filterRow = grid.Rows.FilterRow; var filterRowType = filterRow.GetType(); var getOperatorValueMethod = filterRowType.GetMethod("GetOperatorValue", BindingFlags.NonPublic | BindingFlags.Instance); var filterOperator = getOperatorValueMethod.Invoke(filterRow, new object[] { flt.Column }); if (null != filterOperator) { filterComparisionOperator = (FilterComparisionOperator)filterOperator; Debug.WriteLine(filterComparisionOperator); } // This approach just gets the value of the member variable. // I included it just in case the first method doesn't work for some // reason. // //var columnFilterType = typeof(ColumnFilter); //var filterRowOperatorValueField = columnFilterType.GetField("filterRowOperatorValue", BindingFlags.Instance | BindingFlags.NonPublic); //var filterOperator = filterRowOperatorValueField.GetValue(flt); //filterComparisionOperator = (FilterComparisionOperator)filterOperator; //Debug.WriteLine(filterComparisionOperator); // However we got the value, set the column default. var filterOperatorDefaultValue = (FilterOperatorDefaultValue)Enum.Parse(typeof(FilterOperatorDefaultValue), filterComparisionOperator.ToString()); flt.Column.FilterOperatorDefaultValue = filterOperatorDefaultValue; break; }
thanks Mike! This works great and is exactly what I was looking for. Your warnings are noted. Much appreciated.
Just came across this today, as we have an almost identical requirement, ie we want to rember on a per column per grid basis what filter operator (starts with, contains, etc) the user has selected. I tried it with one of our grids, setting two of the columns to something different and leaving the others as the default. When I run the code though, every time I invoke the method it returns the same value, the default operator. Have I done something wrong - I rewrote in VB.Net, loop over the bands so I can save each band separately, and don't care about the comparison operator, so leave that out. Here is the code I am using:
For Each band In _grid.DisplayLayout.Bands For Each flt As ColumnFilter In band.ColumnFilters Dim filterRow = _grid.Rows.FilterRow Dim filterRowType = filterRow.GetType Dim getOperatorValueMethod = filterRowType.GetMethod("GetOperatorValue", BindingFlags.Instance Or BindingFlags.NonPublic) Dim args = New List(Of UltraGridColumn) From {flt.Column} Dim filterOperator = getOperatorValueMethod.Invoke(filterRow, args.ToArray) Next Next
I've pulled out the bits where I store the result, and also where I pull out and store the othey values we are persisting, but other than that, this is the code I'm using.
Any ideas? Also, I'd like to request access to retrieving and setting this is made public in a future release?
Ah, forget it, the problem is at our end. When we originally looked at saving grid configuration we looked at using SaveAsXml from the DisplayLayout object. Could never get this tuned to export what we wanted, but had apparently tried to avoid too much info in the filters by calling ClearAllFilters. This should have been tied to the SaveAsXml code, but was still getting called before our manual state extraction. Removed that call and now we're getting the values coming through.