You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF DataGrid编程实现:保留旧项排序,禁用新项排序

嘿,我来帮你搞定这个需求——让WPF DataGrid里的旧数据正常保持排序功能,新增的条目却不参与排序。咱们可以基于你现有的SortDataGridByMultipleColumns方法改造,核心思路是给新增项添加一个标记属性,然后通过自定义排序比较器,让排序规则只对非新增项生效,新增项可以固定在列表末尾(或者你想要的位置)。

具体实现步骤

  1. 给数据实体添加新增项标记
    首先,在你的数据类里加一个IsNewItem属性,用来区分是否是刚添加的未保存项:
public class YourDataModel : INotifyPropertyChanged
{
    // 你的原有业务属性...
    private bool _isNewItem;
    public bool IsNewItem
    {
        get => _isNewItem;
        set
        {
            _isNewItem = value;
            OnPropertyChanged(nameof(IsNewItem));
        }
    }

    // 实现INotifyPropertyChanged接口
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
  1. 创建自定义排序比较器
    这个比较器会判断项是否是新增的,对旧数据执行你原来的多列排序逻辑,对新增项直接跳过排序(让它们固定在末尾):
public class DataGridCustomComparer : IComparer
{
    private readonly Dictionary<int, ListSortDirection> _sortRules;
    private readonly DataGrid _targetGrid;

    public DataGridCustomComparer(DataGrid dataGrid, Dictionary<int, ListSortDirection> sortInfo)
    {
        _targetGrid = dataGrid;
        _sortRules = sortInfo;
    }

    public int Compare(object x, object y)
    {
        var itemX = x as YourDataModel;
        var itemY = y as YourDataModel;

        // 处理新增项的排序逻辑:新增项始终排在最后
        if (itemX?.IsNewItem == true && itemY?.IsNewItem == false)
            return 1;
        if (itemX?.IsNewItem == false && itemY?.IsNewItem == true)
            return -1;
        if (itemX?.IsNewItem == true && itemY?.IsNewItem == true)
            return 0; // 都是新增项,保持添加顺序

        // 对旧数据执行原有的多列排序逻辑
        foreach (var sortEntry in _sortRules)
        {
            var column = _targetGrid.Columns[sortEntry.Key];
            // 获取列对应的排序字段名
            var sortProperty = column.SortMemberPath ?? column.DisplayMemberBinding?.Path.Path;
            if (string.IsNullOrEmpty(sortProperty))
                continue;

            var propX = itemX.GetType().GetProperty(sortProperty);
            var propY = itemY.GetType().GetProperty(sortProperty);
            if (propX == null || propY == null)
                continue;

            var valX = propX.GetValue(itemX);
            var valY = propY.GetValue(itemY);

            int compareResult;
            // 处理可比较类型
            if (valX is IComparable compX && valY is IComparable compY)
            {
                compareResult = compX.CompareTo(compY);
            }
            else
            {
                // 非可比较类型按字符串比较
                compareResult = string.Compare(valX?.ToString(), valY?.ToString(), StringComparison.Ordinal);
            }

            // 根据排序方向调整结果
            if (sortEntry.Value == ListSortDirection.Descending)
                compareResult = -compareResult;

            // 当前列有排序差异,直接返回结果
            if (compareResult != 0)
                return compareResult;
        }

        // 所有排序列都相同,保持原有顺序
        return 0;
    }
}
  1. 改造原有的排序方法
    不再用默认的SortDescriptions,而是设置CustomSort来使用我们的自定义比较器:
public static void SortDataGridByMultipleColumns(DataGrid dataGrid, Dictionary<int, ListSortDirection> sortInfo)
{
    // 强制DataGrid退出编辑或新增模式
    RemoveNewAndEdit(dataGrid);

    // 获取数据的CollectionView
    var collectionView = CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);
    if (collectionView == null)
        return;

    // 应用自定义排序
    collectionView.CustomSort = new DataGridCustomComparer(dataGrid, sortInfo);
}

// 你的原有RemoveNewAndEdit方法(假设已实现)
private static void RemoveNewAndEdit(DataGrid dataGrid)
{
    if (dataGrid.IsEditing())
        dataGrid.CommitEdit(DataGridEditingUnit.Row, true);
    if (dataGrid.IsAddingNew())
        dataGrid.CancelEdit();
}
  1. 标记新增项
    在添加新项的时候,记得把IsNewItem设为true;当你保存这个新增项后,把IsNewItem设为false,这样它就会加入正常排序了:
// 添加新项示例
var newItem = new YourDataModel { IsNewItem = true };
YourDataCollection.Add(newItem);

// 保存新增项后更新标记
private void SaveNewItem(YourDataModel item)
{
    // 这里执行你的保存逻辑(比如写入数据库)
    // ...

    // 标记为已保存,参与排序
    item.IsNewItem = false;
    // 重新触发排序
    SortDataGridByMultipleColumns(YourDataGrid, YourSortSettingsDictionary);
}

额外说明

  • 确保你的DataGrid绑定的是ObservableCollection(或其他支持集合视图的数据源),这样CustomSort的变化会自动刷新界面
  • 如果需要调整新增项的位置(比如固定在开头),只需要修改比较器里的返回值即可(把1和-1调换)

内容的提问来源于stack exchange,提问作者Andrew Miller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:22:24