排序与数据绑定和变频器DataGrid列 [英] Sorting on datagrid column with binded data and converter
问题描述
我想在DataGrid中的数据进行排序,但是当我点击已与转换器结合的列的标题,没有任何反应。我使用MVVM模式。示例如下连接。在这个例子中,网格显示柱(型),其显示的人型,因此,我使用转换器(类TypeValueConverter)。当我用这个转换器,电网不排序列类型。
<窗口x:类=GridSort.MainWindow
的xmlns =http://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
的xmlns:我=CLR的命名空间:GridSort
标题=主窗口高度=350宽度=525>
<电网>
<数据网格的ItemsSource ={结合人民}的AutoGenerateColumns =FALSE>
< DataGrid.Resources>
<我:TypeValueConverter X:关键=类型转换器/>
< /DataGrid.Resources>
< DataGrid.Columns>
< DataGridTextColumn绑定={结合姓}标题=名字/>
< DataGridTextColumn绑定={结合姓}标题=姓/>
< DataGridTextColumn绑定={结合转换器= {的StaticResource的ResourceKey =类型转换器}}标题=输入/>
< /DataGrid.Columns>
< /数据网格>
< /网格>
< /窗>
公共类视图模型
{
私人的ICollection<人>人;
公众的ICollection<人>人
{
得到
{
如果(this.people == NULL)
{
this.people =新的名单,其中,人物>();
this.people.Add(新学生(){名字=查尔斯,姓=西蒙斯});
this.people.Add(新学生(){名字=杰克,姓=男爵});
this.people.Add(新教师(){名字=约翰,姓=禅师});
this.people.Add(新学生(){名字=帕特丽夏,姓=菲利普斯});
this.people.Add(新学生(){名字=马丁,姓=韦伯});
}
返回this.people;
}
}
}
公共类TypeValueConverter:的IValueConverter
{
公共对象转换(对象的值,类型TARGETTYPE,对象参数,System.Globalization.CultureInfo文化)
{
如果(价值== NULL)
{
返回DependencyProperty.UnsetValue;
}
返回value.GetType()名称。
}
公共对象ConvertBack(对象的值,类型TARGETTYPE,对象参数,System.Globalization.CultureInfo文化)
{
抛出新的NotImplementedException();
}
}
公共抽象类Person
{
公共字符串名字
{
得到;
组;
}
公共字符串姓
{
得到;
组;
}
}
公共类学生:人
{
}
公共课老师:人
{
}
我解决了这个问题我自己:)
我创建的网格附加属性UseBindingToSort新的行为。当我将此属性设置为true,那么事件排序的网格认购。经过电网火灾事件排序我用用的IValueConverter自定义比较这是在绑定定义。 解决方法是如下:
变化对视图
<数据网格的ItemsSource ={结合人民}的AutoGenerateColumns =FALSE我:GridSortingBehavior.UseBindingToSort =真>
与附加属性的新行为:
公共静态类GridSortingBehavior
{
公共静态只读的DependencyProperty UseBindingToSortProperty = DependencyProperty.RegisterAttached(UseBindingToSort的typeof(布尔)的typeof(GridSortingBehavior),新PropertyMetadata(新PropertyChangedCallback(GridSortPropertyChanged)));
公共静态无效SetUseBindingToSort(DependencyObject的元素,布尔值)
{
element.SetValue(UseBindingToSortProperty,价值);
}
私有静态无效GridSortPropertyChanged(DependencyObject的ELEM,DependencyPropertyChangedEventArgs E)
{
数据网格的网格= ELEM为DataGrid的;
如果(格!= NULL){
如果((布尔)e.NewValue)
{
grid.Sorting + =新DataGridSortingEventHandler(grid_Sorting);
}
其他
{
grid.Sorting - =新DataGridSortingEventHandler(grid_Sorting);
}
}
}
静态无效grid_Sorting(对象发件人,DataGridSortingEventArgs E)
{
DataGridTextColumn CLM = e.Column为DataGridTextColumn;
如果(CLM!= NULL)
{
数据网格的网格=((DataGrid中)发件人);
的IValueConverter转换器= NULL;
如果(clm.Binding!= NULL)
{
约束力181 = clm.Binding为绑定;
如果(binding.Converter!= NULL)
{
转换器= binding.Converter;
}
}
如果(转换器!= NULL)
{
e.Handled =真实;
ListSortDirection方向=(clm.SortDirection!= ListSortDirection.Ascending)? ListSortDirection.Ascending:ListSortDirection.Descending;
clm.SortDirection =方向;
ListCollectionView的LCV =(的ListCollectionView)CollectionViewSource.GetDefaultView(grid.ItemsSource);
lcv.CustomSort =新ComparerWithComparer(转换器,方向);
}
}
}
最后我自定义比较:
类ComparerWithComparer:的IComparer
{
私人System.Windows.Data.IValueConverter转换器;
私人System.ComponentModel.ListSortDirection方向;
公共ComparerWithComparer(System.Windows.Data.IValueConverter转换器,System.ComponentModel.ListSortDirection方向)
{
this.converter =转换器;
this.direction =方向;
}
公众诠释比较(对象x,对象Y)
{
反对transx = this.converter.Convert(X,typeof运算(字符串),空,System.Threading.Thread.CurrentThread.CurrentCulture);
反对transy = this.converter.Convert(Y的typeof(串),空,System.Threading.Thread.CurrentThread.CurrentCulture);
如果(方向== System.ComponentModel.ListSortDirection.Ascending){
返回Comparer.Default.Compare(transx,transy);
}
其他
{
返回Comparer.Default.Compare(transx,transy)*(-1);
}
}
}
而这一切。
I'm trying to sort data in datagrid, but when I click on the header of the column which has binding with the converter, nothing happens. I use MVVM pattern. Example is attached below. In the example, the grid shows column (Type) which displays type of person and therefore I use converter (class TypeValueConverter). When I use this converter, the grid doesn't sort column Type.
<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
{
}
I resolved this issue myself :)
I created new behavior for grid with attached property UseBindingToSort. When I set this property to true then event Sorting on grid is subscribed. After grid fires event sorting I use custom comparer with IValueConverter which is defined in binding. Solution is below:
Change on view
<DataGrid ItemsSource="{Binding People}" AutoGenerateColumns="False" my:GridSortingBehavior.UseBindingToSort="True">
New behavior with attached property:
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);
}
}
}
And finally my custom comparer:
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);
}
}
}
And that's all.
这篇关于排序与数据绑定和变频器DataGrid列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!