gpt4 book ai didi

wpf - 如何按显示的转换值而不是绑定(bind)的源属性值对 DataGridTextColumn 进行排序?

转载 作者:行者123 更新时间:2023-12-03 17:53:03 24 4
gpt4 key购买 nike

如何按显示的、转换的值而不是绑定(bind)的源属性值对 WPF DataGridTextColumn 进行排序?现在它按行 View 模型中的整数值排序,而不是显示转换器返回的文本。我使用 MVVM。

这是一个请求的例子。然而,这是一般性问题。我可以将 MmsClass.Name 放在代表该行的类中。但我需要在所有地方进行适当的排序,而不仅仅是这里。

一行的类:

public class MaintenanceDataItem
{
public MaintenanceDataItem(int classId, Type objectType, object value, IEnumerable<MmsData> rows)
{
ClassId = classId;
TypeOfObject = objectType;
Value = value;
ObjectIds = new List<int>();
MmsDataRows = rows;
}

public int ClassId { get; private set; }
// rest of the properrties omitted
}

转换器:

public class MmsClassToNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
MmsClass mmsClass;
if (MmsClasses.Instance.TryGetValue((int) value, out mmsClass))
{
return mmsClass.Name;
}
return value.ToString();
}

public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return value.Equals(true) ? parameter : Binding.DoNothing;
}
}

xaml 中的列:

            <DataGridTextColumn Header="{StaticResource ResourceKey=MmsStrCondClass}" Binding="{Binding ClassId, Converter={StaticResource mmsclasstonameconverter}}" Width="*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="TextWrapping" Value="NoWrap" />
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

我真的以为默认排序会显示值。如果这不容易解决,那么使用转换器对于 datagridcolumn 就没有多大意义。

最佳答案

不幸的是,这不是一项微不足道的任务。正如@Maverik 正确指出的那样,DataGrid 对基础数据进行排序,而不是转换器吐出的内容。为此,您需要自己排序。首先创建一个类,其中包含一个属性以使用您的自定义排序器,另一个类用于定义要在给定列上使用的排序器:

    public static ICustomSorter GetCustomSorter(DependencyObject obj)
{
return (ICustomSorter)obj.GetValue(CustomSorterProperty);
}

public static void SetCustomSorter(DependencyObject obj, ICustomSorter value)
{
obj.SetValue(CustomSorterProperty, value);
}

// Using a DependencyProperty as the backing store for CustomSorter. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CustomSorterProperty =
DependencyProperty.RegisterAttached("CustomSorter", typeof(ICustomSorter), typeof(CustomSortBehavior), new PropertyMetadata(null));

public static bool GetAllowCustomSort(DependencyObject obj)
{
return (bool)obj.GetValue(AllowCustomSortProperty);
}

public static void SetAllowCustomSort(DependencyObject obj, bool value)
{
obj.SetValue(AllowCustomSortProperty, value);
}

// Using a DependencyProperty as the backing store for AllowCustomSort. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowCustomSortProperty =
DependencyProperty.RegisterAttached("AllowCustomSort", typeof(bool), typeof(CustomSortBehavior), new PropertyMetadata(false, AllowCustomSortChanged));

ICustomSorter 是一个非常简单的接口(interface):

public interface ICustomSorter : IComparer
{
ListSortDirection SortDirection { get; set; }

string SortMemberPath { get; set; }
}

现在您需要从“AllowCustomSort”实现自定义排序:

    private static void AllowCustomSortChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DataGrid control = d as DataGrid;
{
var oldAllow = (bool)e.OldValue;
var newAllow = (bool)e.NewValue;

if (!oldAllow && newAllow)
{
control.Sorting += HandleCustomSorting;
}
else
{
control.Sorting -= HandleCustomSorting;
}
}
}

private static void HandleCustomSorting(object sender, DataGridSortingEventArgs e)
{
//Check if we should even be using custom sorting
DataGrid dataGrid = sender as DataGrid;
if (dataGrid != null && GetAllowCustomSort(dataGrid))
{
//Make sure we have a source we can sort
ListCollectionView itemsSource = dataGrid.ItemsSource as ListCollectionView;
if (itemsSource != null)
{
ICustomSorter columnSorter = GetCustomSorter(e.Column);

//Only do our own sort if a sorter was defined
if (columnSorter != null)
{
ListSortDirection nextSortDirection = e.Column.SortDirection == ListSortDirection.Ascending ?
ListSortDirection.Descending :
ListSortDirection.Ascending;
e.Column.SortDirection = columnSorter.SortDirection = nextSortDirection;
columnSorter.SortMemberPath = e.Column.SortMemberPath;
itemsSource.CustomSort = columnSorter;

//We've handled the sort, don't let the DataGrid mess with us
e.Handled = true;
}
}
}
}

这只是连接 Sorting 事件,然后通过调用提供的 ICustomSorter 对集合进行排序来处理它。

在您的 XAML 中,您创建一个已实现的 ICustomSorter 的实例并使用附加属性,如下所示:

            <DataGridTextColumn Header="Column1" Binding="{Binding Column1, Converter={StaticResource Column1Converter}}" IsReadOnly="True"
util:CustomSortBehavior.CustomSorter="{StaticResource Column1Comparer}"/>

这很痛苦,您必须对所有转换后的值进行自定义排序,但它确实允许您在 DataGrid 中执行此操作。

关于wpf - 如何按显示的转换值而不是绑定(bind)的源属性值对 DataGridTextColumn 进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39984062/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com