Reputation: 2375
I have a Datagrid
which has only one column and I want applying a custom sort on it. Currently, When I search the word "Clark", Datagrid displays filtered result as this:
David Clark
Clark David
But I want to display that item which start with FilterString
at first row:
Clark David
David Clark
If user search "David", the result should be:
David Clark
Clark David
This is my datagrid:
<TextBox Name="SearchBox" KeyUp="SearchBox_OnKeyUp" />
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding WordsCollectionView}">
<DataGrid.Columns>
<DataGridTextColumn Width="*" Binding="{Binding}" />
</DataGrid.Columns>
</DataGrid>
And this is my codebehind:
string[] words = { "David Clark", "Clark David", "John Smith"};
private string _filterString = "";
private ICollectionView _wordsCollectionView;
public ICollectionView WordsCollectionView
{
get => _wordsCollectionView;
set { _wordsCollectionView = value; OnPropertyChanged(); }
}
public MainWindow()
{
InitializeComponent();
WordsCollectionView = CollectionViewSource.GetDefaultView(words);
WordsCollectionView.Filter = FilterResult;
DataContext = this;
}
public string FilterString
{
get => _filterString;
set
{
_filterString = value;
OnPropertyChanged();
FilterCollection();
}
}
public bool FilterResult(object obj)
{
string str = obj as string;
return str.Contains(FilterString);
}
private void FilterCollection()
{
_wordsCollectionView?.Refresh();
}
private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)
{
FilterString = (sender as TextBox).Text;
}
Upvotes: 0
Views: 249
Reputation: 169200
If you cast WordsCollectionView
to a ListCollectionView
, you could set its CustomSort
property to an IComparer
where you implement your custom sorting logic. Something like this:
public MainWindow()
{
InitializeComponent();
WordsCollectionView = CollectionViewSource.GetDefaultView(words);
WordsCollectionView.Filter = FilterResult;
var listCollectionView = WordsCollectionView as ListCollectionView;
if (listCollectionView != null)
listCollectionView.CustomSort = new CustomSorter(this);
DataContext = this;
}
private class CustomSorter : IComparer
{
private readonly MainWindow _window;
public CustomSorter(MainWindow window)
{
_window = window;
}
public int Compare(object x, object y)
{
int a = x?.ToString().IndexOf(_window.FilterString) ?? -1;
int b = y?.ToString().IndexOf(_window.FilterString) ?? -1;
return a.CompareTo(b);
}
}
Upvotes: 1
Reputation: 4943
You can set both filtering and sorting on an ICollectionView
:
WordsCollectionView.Filter = FilterResult
WordsCollectionView.SortDescriptions.Add(new SortDescription("", ListSortDirection.Ascending)); //words have no property
See this MSDN page for full details.
Note that this will result in the sorting you want, but for more advanced sorting you should consider having two columns instead of one, one for the first name and one for the last name.
Upvotes: 1