I have a GridViewDataColumn that binds to a complex model (Custom class with a few properties and a ToString method)
The GridViewDataColumn also has a CustomGridFilter which is able to filter the column and has it's own popup.
But .. now the users also want to Order by this column - but nothing happens when clicking on the Column Header.
What am i missing ?
<telerik:GridViewDataColumn Width="100"
DataMemberBinding="{Binding YearRange}"
Header="Ã…rgang">
<telerik:GridViewDataColumn.FilteringControl>
<local:CustomGridFilter Aargang="{Binding ElementName=root, Path=VintageYear, Mode=TwoWay}" />
</telerik:GridViewDataColumn.FilteringControl>
</telerik:GridViewDataColumn>
public class YearRange : IEquatable<int>
{
public int FromYear { get; set; }
public int ToYear { get; set; }
public int Year { get; set; }
public override string ToString()
{
if (FromYear == ToYear)
return FromYear.ToString();
return FromYear + "-" + ToYear;
}
#region Equals, GetHashCode
#region Comparison operators override
}
public partial class CustomGridFilter : UserControl, IFilteringControl, INotifyPropertyChanged
{
private GridViewBoundColumnBase column;
private CompositeFilterDescriptor compositeFilter;
private FilterDescriptor rangeFilter;
#region INotifyPropertyChanged
public void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region IsActive DependencyProperty
public bool IsActive
{
get { return (bool)GetValue(IsActiveProperty); }
set { SetValue(IsActiveProperty, value); }
}
public static readonly DependencyProperty IsActiveProperty =
DependencyProperty.Register(
"IsActive",
typeof(bool),
typeof(CustomGridFilter),
new PropertyMetadata(false));
#endregion
#region Aargang DependencyProperty
public int? Aargang
{
get { return (int?)GetValue(AargangProperty); }
set { SetValue(AargangProperty, value); }
}
public static readonly DependencyProperty AargangProperty =
DependencyProperty.Register(
"Aargang",
typeof(int?),
typeof(CustomGridFilter),
new PropertyMetadata(
null,
(sender, evt) => { ((CustomGridFilter)sender).OnPropertyChanged("Aargang"); }
)
);
#endregion
public CustomGridFilter()
{
InitializeComponent();
DataContext = this;
PropertyChanged += CustomGridFilter_PropertyChanged;
}
private void CustomGridFilter_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Aargang" && Aargang>1900 && Aargang<2100)
{
OnFilter(null, null);
}
}
public void Prepare(Telerik.Windows.Controls.GridViewColumn column)
{
this.column = column as GridViewBoundColumnBase;
if (this.column == null)
{
return;
}
if (compositeFilter == null)
{
CreateFilters();
}
}
private void CreateFilters()
{
string dataMember = column.DataMemberBinding.Path.Path;
compositeFilter = new CompositeFilterDescriptor();
rangeFilter = new FilterDescriptor(dataMember, FilterOperator.IsEqualTo, null);
compositeFilter.FilterDescriptors.Add(rangeFilter);
}
private void OnFilter(object sender, RoutedEventArgs e)
{
rangeFilter.Value = new YearRange { Year = Aargang ?? 0 };
if (!column.DataControl.FilterDescriptors.Contains(compositeFilter))
{
column.DataControl.FilterDescriptors.Add(compositeFilter);
}
IsActive = true;
var popup = this.ParentOfType<System.Windows.Controls.Primitives.Popup>();
if (popup != null)
{
popup.IsOpen = false;
}
}
private void OnClear(object sender, RoutedEventArgs e)
{
if (column.DataControl.FilterDescriptors.Contains(compositeFilter))
{
column.DataControl.FilterDescriptors.Remove(compositeFilter);
}
Aargang = 0;
IsActive = false;
var popup = this.ParentOfType<System.Windows.Controls.Primitives.Popup>();
if (popup != null)
{
popup.IsOpen = false;
}
}
}
Thank you for the provided code snippets.
I tried replicating the issue you described and indeed, for the sorting to work as expected, you need to implement the IComparable interface on the YearRange class so that the RadGridView control understands how the sorting should be performed. For example:
public int CompareTo(YearRange other) { return this.Year.CompareTo(other.Year); }
Hi Dilyan, thanks for the hints.
It worked in 1 out of 2 GridViews ..
but on the 2nd im getting this error :
Working:
- ItemsSource bound directly to collection (ObservableCollection)
Not Working
- ItemsSource bound to CollectionViewSource
Hi Martin,
Thank you for the provided stack trace.
Would you, however, be able to demonstrate the exception in a small sample project so that I can further investigate its cause as I am currently unable to replicate the same exception at my end?
Thank you in advance for your cooperation on the matter.
I've managed to create a sample solution that shows the error.
it seems that the error truly stems from the CollectionViewSouce...
Hello Martin,
Thank you very much for the provided project. I can confirm that I was able to replicate the issue at my end.
Indeed, this seems to stem from the use of a CollectionViewSouce. With this said, would you find it possible to use the QueryableCollectionViewSource class instead?
I've updated the project you provided to demonstrate how you can use the QueryableCollectionViewSource. Please have a look and let me know if the same would be applicable in your original application.