c# - 扩展 TreeView 控件以进行增量过滤/搜索

标签 c# .net winforms treeview

我正在尝试扩展winforms TreeView控件以允许增量过滤和搜索,类似于VS2012/VS2013中的解决方案资源管理器。

理想情况下,我希望它能够以最少的代码更改替换现有的 TreeView - 就消费者而言,唯一的区别是方法 void Filter(string) 。正因为如此,我认为这对于Nodes来说是有意义的。属性返回 TreeNodeCollection包含所有节点,甚至由于应用的过滤器而未显示的节点。

我编写了处理过滤的代码,它实际上工作得很好,除非我访问base.Nodes ,它返回我过滤的节点,而不是完整列表。

我遇到的问题是,我无法克隆或创建 TreeNodeCollection 的新实例,因为构造函数被标记为内部。所以我理想的代码看起来像这样:

public class TreeViewEx : TreeView
{
    // results in a compiler error:
    private TreeNodeCollection _allNodes = new TreeNodeCollection();

    public new TreeNodeCollection Nodes { get { return _allNodes; } }

    public TreeNodeCollection FilteredNodes { get { return base.Nodes; } }

    public void Filter(string searchString)
    {
        base.BeginUpdate();
        base.Nodes.Clear();
        foreach (TreeNode node in FilterInternal(_allNodes, searchString))
        {
            base.Nodes.Add(node);
        }
        base.EndUpdate();
    }
}

正如您所看到的,我正在尝试将 UI 中显示的节点与消费者将访问的节点分离。当然是TreeNodeCollection仅具有内部构造函数,我无法创建新实例或克隆它。

我考虑过这两个选项,但听起来都不是好的解决方案:

  1. 使用反射来实例化 TreeNodeCollection第二个列表的对象(由于内部构造函数)。这个选项看起来比 #2 更有效,但当然我正在创建一个我不应该创建的对象的实例。
  2. 在内存中实例化第二个 TreeView 并使用其中的 Nodes 属性来维护我的第二个列表。这看起来可能会产生很大的开销。

我希望最终结果仍然是 TreeNodeCollection因此,TreeView 可用于以最少的代码替换我们现有的控件,并且我们确实有几个地方使用 Find方法,该方法在 List<TreeNode> 中不存在.

有人对如何处理这个问题有任何建议吗?考虑到我的两个考虑因素,性能/资源方面怎么样?

谢谢

更新1:

根据帕特的建议,我决定退后一步,避免惹恼 Nodes共。所以现在我添加了 List<TreeNode> AllNodes属性(property)并拥有 Nodes只是显示 TreeView 中出现的节点(过滤后的列表),所以现在更简单了。

我现在的问题是,我怎么知道什么时候 AllNodes添加了一个项目,这样我就可以保留 Nodes同步中?我考虑过使用 BindingList所以我有 ListChanged事件,但随后我需要让我的 TreeNode 和节点的子/孙/等( AllNodes[0].Nodes )使用继承自 TreeNode 的自定义类。并更改 Nodes属性(property),和TreeNode.Nodes是不可重写的。还有别的办法吗?我可以创建一个名为 NodeExs 之类的新属性,但这似乎非常不直观,我可能会看到另一个开发人员稍后出现并拔出他的头发,因为 Nodes 属性在那里但不起作用。

最佳答案

关于您提出的解决方案,#2 已被淘汰,因为 TreeNode不能属于多个控件。虽然可以创建 TreeNodeCollection 的实例通过反射,它不会很有用,因为它设计为耦合到 TreeView或另一个TreeNode 。您将无法在集合中添加/删除节点。

Because of this, I think it would make sense for the Nodes property to return the TreeNodeCollection with ALL nodes, even ones not showing because of an applied filter.

我不同意,TreeNodeCollectionNodes 返回框架和操作系统使用属性来呈现控件。您确实不想隐藏此属性或更改其功能。

如果消费者需要访问 _allNodes ,创建一个List<TreeNode> AllNodes属性或使用自定义集合。

关于c# - 扩展 TreeView 控件以进行增量过滤/搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24923419/

相关文章:

C# 程序集,程序集中有什么?

c# - 绑定(bind)到 Properties.Settings.Default.myString 的文本框文本不会更新 myString

c# - 将 datagridview 从一种形式传递到另一种形式 C#

c# - 如何捕获堆栈跟踪?

C#,后台 worker 类

c# - 运行大型 SQL 语句并填充 gridview

asp.net - 什么是 ASP.NET 迁移中的鉴别器列?

c# - .net/C# 的 Html 解析器和对象模型

winforms - 是否可以在不显示控制台窗口的情况下运行 f# 脚本?

c# - 如何避免在 .NET Windows 窗体中创建重复的窗体?