Файл MainWindow.xaml
<Window x:Class="WpfDataGridCustomSort.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfDataGridCustomSort"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<DataGrid x:Name="MyGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding MyData}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
FontFamily="Gisha" FontSize="20">
<DataGrid.Columns>
<DataGridTextColumn Header="Customer" Binding="{Binding Customer}" />
<DataGridTextColumn Header="Item" Binding="{Binding Item}"/>
<DataGridTextColumn Header="Price" Binding="{Binding Price}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
C#
Файл MainWindow.xaml.cs
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfDataGridCustomSort
{
public class MyShop
{
public string Customer { get; set; }
public string Item { get; set; }
public string Price { get; set; }
}
public partial class MainWindow : Window
{
public ObservableCollection<MyShop> MyData { get; set; }
public MainWindow()
{
InitializeComponent();
// for binding
this.DataContext = this;
// data for grid
MyData = new ObservableCollection<MyShop>()
{
new MyShop() {Customer="ACME", Item="Widget", Price="RUB:100"},
new MyShop() {Customer="ACME", Item="Widget", Price="EURO:100"},
new MyShop() {Customer="ACME", Item="Tyre", Price="RUB:200"},
new MyShop() {Customer="Amazon", Item="Pen", Price="EURO:50"},
new MyShop() {Customer="Amazon", Item="Paper", Price="RUB:20"},
new MyShop() {Customer="Autodesk", Item="CAD", Price="DOLLARS:10"},
new MyShop() {Customer="Autodesk", Item="File", Price="RUB:40"},
new MyShop() {Customer="ABC", Item="Flowers", Price="DOLLARS:503"},
new MyShop() {Customer="ABC", Item="Sand", Price="DOLLARS:50"}
};
// sorting
MyGrid.Sorting += new DataGridSortingEventHandler(CustomSorting);
}
void CustomSorting(object sender, System.Windows.Controls.DataGridSortingEventArgs e)
{
DataGridColumn column = e.Column;
// custom sort for column
if (column.SortMemberPath == "Price")
{
// Prevent auto sorting
e.Handled = true;
// sort direction
column.SortDirection = (column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;
// comparer
ListCollectionView lcv = (ListCollectionView)CollectionViewSource.GetDefaultView(MyGrid.ItemsSource);
IComparer comparer = new MyComparer(column.SortDirection.Value);
lcv.CustomSort = comparer;
}
}
}
}
C#
Файл MyComparer.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Linq;
namespace WpfDataGridCustomSort
{
public class MyComparer : IComparer
{
public MyComparer()
{
}
public MyComparer(ListSortDirection sortDirection)
{
SortDirection = sortDirection;
}
public ListSortDirection SortDirection { get; set; }
public int Compare(object obj1, object obj2)
{
string text1 = (obj1 as MyShop)?.Price;
string text2 = (obj2 as MyShop)?.Price;
if (text1 == null || text2 == null)
{
return 0;
}
// find position 'i' where different symbols
// example: text1 = "HD156"
// example: text2 = "HD1789"
// result: i = 3 ^
var i = 0;
while (i < text1.Length && i < text2.Length && text1[i] == text2[i])
{
i++;
}
// make numbers (from position 'i' and until digit)
// example: strNumber1 = "56" strNumber2 = "789"
var strNumber1 = new string(text1.Substring(i).ToList().TakeWhile(c => Char.IsDigit(c)).ToArray());
var strNumber2 = new string(text2.Substring(i).ToList().TakeWhile(c => Char.IsDigit(c)).ToArray());
// compare as numbers
if (int.TryParse(strNumber1, out var number1) && int.TryParse(strNumber2, out var number2))
{
return SortDirection == ListSortDirection.Ascending ? number1.CompareTo(number2) : number2.CompareTo(number1);
}
// compare as strings
return SortDirection == ListSortDirection.Ascending ? text1.CompareTo(text2) : text2.CompareTo(text1);
}
}
}
C#
//MyGrid.Sorting += new DataGridSortingEventHandler(CustomSorting);