如何防止 XtraTreeList 中的列排序?

How to prevent column sorting in XtraTreeList?

我正在使用 devexpress 并且有一个包含多列的树列表。

默认情况下,根据客户要求,数据以 "ascending" 排序呈现。

问题:

我有一个按钮可以禁用列排序。我有以下两个属性可以使用:“OptionsColumn.AllowSort”和 SortOrder。问题是,即使我设置了 OptionsColumn.AllowSort = false,在更改列值时仍然会触发排序,因为我有一个 AscendingSortOrder

我发现,如果我将 OptionsColumn.AllowSort = falseSortOrder 更改为 None,当我更改sortOrder 到 None 这会触发让客户感到困惑的排序。

我想要的:

简而言之,我需要 "Freeze" 排序,这意味着当用户单击 "DisableSorting" 时,列表不会像将 sortOrder 更改为 "none" 时那样排序,它将保持原样是并且在更改值时不应触发排序。

代码

禁用按钮

    private void DisableSorting_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
    {
        foreach (var c in xtlItemList.Columns)
        {
            c.OptionsColumn.AllowSort = false; // disable sorting on all columns
        }

        EnableSorting= false; // global variable indicating that the sorting shoult be disabled

    }

treeList 开始排序事件:

        private void xtlItemList_StartSorting(object sender, EventArgs e)
        {
            try
            {

                var tree = (MatrixXTreeList)sender;
                DevExpress.XtraTreeList.Columns.TreeListColumn col = tree.GetSortColumn(0);

                if (EnableSorting == true) // if sorting enabled
                {

                    var treeTest = (MatrixXTreeList)sender;

                    DevExpress.XtraTreeList.Columns.TreeListColumn col2 = treeTest.GetSortColumn(0);


                    if (col != null)
                        SetSortColumnID((MatrixXTreeList)sender, afterUpdate);
                    else
                    {
                        col.SortOrder = SortOrder.None;
                    }
                }

                else
                {
                    col.SortOrder = SortOrder.None; // if sorting diabled, 
//problem still triggers a sort since the SortOrder is changed from Ascending to None
                }
            }

            catch (Exception ex)
            {

            }
        }

我如何完成期望的行为?

OptionsColumn.AllowSort 帮助文章描述了此 属性 enables/disables 仅最终用户功能。这就是为什么期望 TreeList 的节点仍然根据更改的单元格值进行排序的原因。 如果您需要禁用排序功能但按当前顺序显示节点,我建议您在现有数据源的基础上创建一个新数据源,保持当前节点顺序。然后,将这个新数据源分配给您的 TreeList,并将 SortOrder 属性 设置为 None。当您打开排序功能时,将原始数据源分配给控件。

感谢@Svetlana,我设法解决了这个问题。解决方法如下:

首先,我一直在寻找保持列值不变的方法,因此我通过执行以下操作实现了这一点:

       public List<string> myValues= new List<string>();

        int count = xtlItemList.Nodes.Count; // number of nodes in three

        for (int i = 0; i < count; i++)
        {
            var columnID1 = xtlItemList.Columns[2]; // get the column with index of 2
            var cellValue = xtlItemList.Nodes[i][columnID1]; // get value

            myStrings.Add(cellValue.ToString()); // save value
        }

        // change sort order

        xtlItemList.BeginSort();
        xtlItemList.Columns[2].SortOrder = SortOrder.None;
        xtlItemList.EndSort();

        // return the values
        for (int i = 0; i < myStrings.Count; i++)
        {
            var columnID1 = xtlItemList.Columns[2];
            xtlItemList.Nodes[i].SetValue(columnID1, myStrings[i]);
        }

然而

以上是错误的,因为我会为每一行提供错误的值。由于排序已更改,行已重新排列,因此值不属于相应的已排序行。

我通过将节点保存在列表中然后在排序后设置节点的位置来解决这个问题,如下所示:

        int count = xtlItemList.Nodes.Count;

        List<TreeListNode> nodes = new List<TreeListNode>();
        nodes.AddRange(xtlItemList.Nodes); // save the nodes with their position

        xtlItemList.BeginSort();
        xtlItemList.Columns[2].SortOrder = SortOrder.None;
        xtlItemList.EndSort();

        for (int i = 0; i < nodes.Count; i++)
        {
            xtlItemList.SetNodeIndex(nodes[i], i); // set nodes to the original position
        }