我想在DataGrid中的数据进行排序,但是当我点击已经使转换器结合的列标题,没有任何反应。 我使用MVVM模式。 例子在下面附接。 在该示例中,网格显示列(类型),其显示的人型,因此,我使用转换器(类TypeValueConverter)。 当我使用这个转换器,电网不排序列类型。
<Window x:Class="GridSort.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:GridSort"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid ItemsSource="{Binding People}" AutoGenerateColumns="False">
<DataGrid.Resources>
<my:TypeValueConverter x:Key="typeConverter" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FirstName}" Header="FirstName" />
<DataGridTextColumn Binding="{Binding Surname}" Header="Surname" />
<DataGridTextColumn Binding="{Binding Converter={StaticResource ResourceKey=typeConverter}}" Header="Type" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
public class ViewModel
{
private ICollection<Person> people;
public ICollection<Person> People
{
get
{
if (this.people == null)
{
this.people = new List<Person>();
this.people.Add(new Student() { FirstName = "Charles", Surname = "Simons" });
this.people.Add(new Student() { FirstName = "Jake", Surname = "Baron" });
this.people.Add(new Teacher() { FirstName = "John", Surname = "Jackson" });
this.people.Add(new Student() { FirstName = "Patricia", Surname = "Phillips" });
this.people.Add(new Student() { FirstName = "Martin", Surname = "Weber" });
}
return this.people;
}
}
}
public class TypeValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
{
return DependencyProperty.UnsetValue;
}
return value.GetType().Name;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public abstract class Person
{
public string FirstName
{
get;
set;
}
public string Surname
{
get;
set;
}
}
public class Student : Person
{
}
public class Teacher : Person
{
}
我解决了这个问题我自己:)
我创建了具有附加属性UseBindingToSort电网新的行为。 当我将此属性设置为true,那么事件对电网排序订阅。 网格火灾事件排序后我用的IValueConverter自定义比较器,其在结合定义。 解决方案低于:
在查看更改
<DataGrid ItemsSource="{Binding People}" AutoGenerateColumns="False" my:GridSortingBehavior.UseBindingToSort="True">
新的行为与附加属性:
public static class GridSortingBehavior
{
public static readonly DependencyProperty UseBindingToSortProperty = DependencyProperty.RegisterAttached("UseBindingToSort", typeof(bool), typeof(GridSortingBehavior), new PropertyMetadata(new PropertyChangedCallback(GridSortPropertyChanged)));
public static void SetUseBindingToSort(DependencyObject element, bool value)
{
element.SetValue(UseBindingToSortProperty, value);
}
private static void GridSortPropertyChanged(DependencyObject elem, DependencyPropertyChangedEventArgs e)
{
DataGrid grid = elem as DataGrid;
if (grid != null){
if ((bool)e.NewValue)
{
grid.Sorting += new DataGridSortingEventHandler(grid_Sorting);
}
else
{
grid.Sorting -= new DataGridSortingEventHandler(grid_Sorting);
}
}
}
static void grid_Sorting(object sender, DataGridSortingEventArgs e)
{
DataGridTextColumn clm = e.Column as DataGridTextColumn;
if (clm != null)
{
DataGrid grid = ((DataGrid)sender);
IValueConverter converter = null;
if (clm.Binding != null)
{
Binding binding = clm.Binding as Binding;
if (binding.Converter != null)
{
converter = binding.Converter;
}
}
if (converter != null)
{
e.Handled = true;
ListSortDirection direction = (clm.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;
clm.SortDirection = direction;
ListCollectionView lcv = (ListCollectionView)CollectionViewSource.GetDefaultView(grid.ItemsSource);
lcv.CustomSort = new ComparerWithComparer(converter, direction);
}
}
}
最后我的自定义比较:
class ComparerWithComparer : IComparer
{
private System.Windows.Data.IValueConverter converter;
private System.ComponentModel.ListSortDirection direction;
public ComparerWithComparer(System.Windows.Data.IValueConverter converter, System.ComponentModel.ListSortDirection direction)
{
this.converter = converter;
this.direction = direction;
}
public int Compare(object x, object y)
{
object transx = this.converter.Convert(x, typeof(string), null, System.Threading.Thread.CurrentThread.CurrentCulture);
object transy = this.converter.Convert(y, typeof(string), null, System.Threading.Thread.CurrentThread.CurrentCulture);
if (direction== System.ComponentModel.ListSortDirection.Ascending){
return Comparer.Default.Compare(transx, transy);
}
else
{
return Comparer.Default.Compare(transx, transy) * (-1);
}
}
}
就这样。
我用Juptin的解决方案。 但在我的情况下,我使用ConverterParameter。 所以,我把它添加到自己的代码:
class ComparerWithComparer : IComparer
{
private IValueConverter converter;
private ListSortDirection direction;
private object parameter;
public ComparerWithComparer(IValueConverter converter, ListSortDirection direction, object parameter)
{
this.converter = converter;
this.direction = direction;
this.parameter = parameter;
}
public int Compare(object x, object y)
{
object transx = converter.Convert(x, typeof(string), parameter, System.Threading.Thread.CurrentThread.CurrentCulture);
object transy = converter.Convert(y, typeof(string), parameter, System.Threading.Thread.CurrentThread.CurrentCulture);
if (direction == ListSortDirection.Ascending)
{
return Comparer.Default.Compare(transx, transy);
}
return Comparer.Default.Compare(transx, transy) * (-1);
}
}
static void grid_Sorting(object sender, DataGridSortingEventArgs e)
{
DataGridTextColumn column = e.Column as DataGridTextColumn;
if (column != null)
{
DataGrid grid = ((DataGrid)sender);
IValueConverter converter = null;
object parameter = null;
if (column.Binding != null)
{
Binding binding = column.Binding as Binding;
if (binding.Converter != null)
{
converter = binding.Converter;
}
parameter = binding.ConverterParameter;
}
if (converter != null)
{
e.Handled = true;
ListSortDirection direction = (column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;
column.SortDirection = direction;
var listCollectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(grid.ItemsSource);
listCollectionView.CustomSort = new ComparerWithComparer(converter, direction,parameter);
}
}
}
您正在使用MVVM。 如果你不能添加属性Type
,以您的Person
类
public abstract class Person
{
public string FirstName { get; set; }
public string Surname { get; set; }
public string Type
{
get { return this.GetType().Name; }
}
}
你应该创建一个PersonViewModel
public class PersonViewModel
{
public Person Person { get; private set; }
public PersonViewModel(Person person)
{
this.Person = person;
}
public string Type
{
get { return this.Person.GetType().Name; }
}
}
适应你的人收藏
private ICollection<PersonViewModel> people;
public ICollection<PersonViewModel> People
{
get
{
if (this.people == null)
{
this.people = new List<PersonViewModel>();
this.people.Add(new PersonViewModel(new Student { FirstName = "Charles", Surname = "Simons" }));
this.people.Add(new PersonViewModel(new Student { FirstName = "Jake", Surname = "Baron" }));
this.people.Add(new PersonViewModel(new Teacher { FirstName = "John", Surname = "Jackson" }));
this.people.Add(new PersonViewModel(new Student { FirstName = "Patricia", Surname = "Phillips" }));
this.people.Add(new PersonViewModel(new Student { FirstName = "Martin", Surname = "Weber" }));
}
return this.people;
}
}
并使用此XAML
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Person.FirstName}" Header="FirstName" />
<DataGridTextColumn Binding="{Binding Person.Surname}" Header="Surname" />
<DataGridTextColumn Binding="{Binding Type}" Header="Type" />
</DataGrid.Columns>