【问题标题】:Prevent persistent edited label after label edit in listview C#在listview C#中编辑标签后防止持久编辑标签
【发布时间】:2017-11-14 04:26:25
【问题描述】:

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

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

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

这是我当前逻辑的一个 sn-p:

    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 中编辑标签。然后,单击“刷新”,可以看到问题。我包括了一个“显示实际数据”按钮来查看没有断点的列表项以及我真正希望列表视图在编辑标签后显示的内容。为确保您发现问题,请务必编辑标签并指定新名称,以便在按字母顺序排序时重新排列。

示例项目的下载链接:https://app.box.com/s/t24ej9hbokcr3qcg8nkbs8slknf5ez5w

【问题讨论】:

  • 我只阅读了问题的最后一行并猜测:执行this.Invalidate()ctrl.Invalidate() 以触发Paint 事件。
  • 感谢您的输入,但它似乎不起作用。我尝试将Invalidate() 放在AfterLabelEdit 事件的开头和结尾,但结果仍然相同:(
  • 肯定有 CodeProject 或 MSDN 可以证明这一点,docs.microsoft.com/en-us/dotnet/framework/winforms/controls/…codeproject.com/Articles/5064/…,还有其他的。如果您需要帮助,使用minimal reproducible example 会更容易
  • @JeremyThompson 我查看了您链接的这两个资源,虽然它们肯定有助于从头开始文件浏览器,但我找不到任何解决方案来解决我的具体问题,因为这些实现没有重命名功能。然而,在进一步挖掘之后,msdn.microsoft.com/en-us/library/… 根据那篇文章,编辑后的文本只会在事件发生后提交。所以我想我搞砸了:/
  • 如果您能给我们专门用于重现此标签编辑的 MCVE/代码,我会看看。

标签: c# winforms listview windows-explorer


【解决方案1】:

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

由于 ListView.AfterLabelEdit 事件发生在标签编辑提交之前,因此在此事件的处理程序中调用 ListView.Sort 方法将使用原始值对项目进行排序。

所以在ListView.AfterLabelEdit() 中运行我的UpdateListView() 代码会导致我在上面的问题中提到的listview 错误。另请注意,在这种情况下,我的列表视图位于 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)));
    }

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多