在列表视图 C# 中编辑标签后防止持久编辑标签

Prevent persistent edited label after label edit in listview C#

在我的 Winforms 应用程序中,我希望允许用户像在 windows 资源管理器中重命名文件或文件夹时那样编辑列表视图项标签。我现在想要实现的是 windows 资源管理器在重命名文件或文件夹时的确切行为。

为了达到这种效果,我调用了一种方法,该方法重命名 AfterLabelEdit 事件中受影响的 file/folder,然后继续重新填充我的列表视图。如果重要的话,我的列表视图是一个虚拟列表视图,因此我的所有项目都存储在字典中。

我现在遇到的问题是,虽然文件正确重命名并且列表视图随着新名称反映在列表中而更新,但编辑后的标签保持不变,所以现在我看到 2 个具有相同名称的列表视图项目,其中一个其中一个是经过本地化编辑的文本,而另一个是实际文本。结果是本地化标签现在代表一个列表视图不会显示的具有另一个名称的文件。

这是我当前逻辑的一个片段:

    private void UpdateListView(int index, string NewName)
    {
        items[index] = NewName;
        items.Sort();
        listViewItemsList.Clear();

        foreach(string item in items)
        {
            ListViewItem Item = new ListViewItem();
            Item.Text = item;
            listViewItemsList.Add(Item);
        }

        listView1.BeginUpdate();
        listView1.VirtualListSize = listViewItemsList.Count;
        listView1.EndUpdate();
    }

    private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e)
    {
        string newName = e.Label;
        UpdateListView(e.Item, newName);
    }

有谁知道我如何在删除标签编辑完成的本地化标签文本的同时在编辑后刷新我的列表视图?

编辑:对于那些希望看到实际问题的人,请随时下载此项目文件并在 listView 中编辑标签。然后,点击"Refresh",就可以看到问题了。我包含了一个 "Show Actual Data" 按钮来查看没有断点的列表项以及我实际希望列表视图在编辑标签后显示的内容。为确保您看到问题,请务必编辑标签并提供新名称,以便在按字母顺序排序时重新排列。

下载 link 示例项目:https://app.box.com/s/t24ej9hbokcr3qcg8nkbs8slknf5ez5w

对于可能遇到此问题的任何人,我设法通过使用 listView.BeginInvoke(); 解决了问题所以我的解决方案是 运行 我的 UpdateListView()BeginInvoke() 方法中而不是根据 MSDN 在 listView.AfterLabelEdit() 方法中,

Because the ListView.AfterLabelEdit event takes place before the label edit is committed, calling the ListView.Sort method in a handler for this event will sort the item using the original value.

所以 运行 在 ListView.AfterLabelEdit() 中使用我的 UpdateListView() 代码会导致我在上面的问题中提到的列表视图错误。另请注意,在这种情况下,我的列表视图位于 virtualMode 中,因此我的列表视图基于列表。这是我的最新代码:

private void UpdateListView(int index, string NewName)
    {
            items[index] = NewName;
            items.Sort();
            listViewItemsList.Clear();

        foreach(string item in items)
        {
            ListViewItem Item = new ListViewItem();
            Item.Text = item;
            listViewItemsList.Add(Item);
        }

        listView1.BeginUpdate();
        listView1.VirtualListSize = listViewItemsList.Count;
        listView1.EndUpdate();
    }

private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e)
    {
        string newName = e.Label;
        listView1.BeginInvoke(new MethodInvoker(() => UpdateListView(e.Item, newName)));
    }

我将更新原始问题中的代码片段,以便更加一致并且更容易看到更改。