在 C# winforms 应用程序中使用文本框过滤 Treeview

     2023-02-27     48

关键词:

【中文标题】在 C# winforms 应用程序中使用文本框过滤 Treeview【英文标题】:Filter a Treeview with a Textbox in a C# winforms app 【发布时间】:2012-01-05 19:34:10 【问题描述】:

我的 C# winform 中有一个 TreeView。我希望能够通过搜索框添加搜索功能。 基本上当用户输入字母时(我猜是 _TextChanged 事件),我只显示包含输入字母的子节点的节点...

我的 TreeView 包含 53 个父节点,总共超过 15000 个节点,所以我需要一些高性能的东西。我从加载到 DataTable 的 csv 构建 TreeView,然后进行查询以获取具有关联子节点的父节点...

更新

我有个主意。 最终目标是当用户双击子节点时,它会被添加到 listView。

我首先在一个简单的列表视图中实现了这个搜索功能,我没有将我的数据分类。

我的想法是,一旦用户开始输入内容,我就会关闭树视图并改为显示列表视图...

我会尝试并实施,看看它在性能方面有什么好处...欢迎任何对此想法的批评。

【问题讨论】:

15000 - 如果您在现代 PC 上运行,文本节点不会太多。你甚至可以过滤树,关键是要有一个聪明的策略来避免性能问题。我将尝试描述一个。列表的解决方案在技术上是可以的,但我猜不是预期的和最好的用户体验。 你试过暴力破解方法了吗?一个好的 ole foreach(ParentNode.ChildNodes 中的 TreeNode 节点)? 【参考方案1】:

最后这就是我所做的,它符合我的要求。 我首先复制我的 TreeView 并存储到 fieldsTreeCache 中。然后我清除fieldsTree。然后我搜索缓存并将包含我的搜索参数的任何节点添加到 fieldsTree。请注意,一旦您搜索,您将不再拥有显示的父节点。您只需获得所有终端节点。我这样做是因为如果没有,我有 2 个选择:

展开所有包含匹配子节点的父节点,但速度很慢,并且一个父节点可能有 50 个子节点,这在视觉上不太好。

不展开父节点,但您只获得类别而不是您正在搜索的子节点。

void fieldFilterTxtBx_TextChanged(object sender, EventArgs e)

    //blocks repainting tree till all objects loaded
    this.fieldsTree.BeginUpdate();
    this.fieldsTree.Nodes.Clear();
    if (this.fieldFilterTxtBx.Text != string.Empty)
    
        foreach (TreeNode _parentNode in _fieldsTreeCache.Nodes)
        
            foreach (TreeNode _childNode in _parentNode.Nodes)
            
                if (_childNode.Text.StartsWith(this.fieldFilterTxtBx.Text))
                
                    this.fieldsTree.Nodes.Add((TreeNode)_childNode.Clone());
                
            
        
    
    else
    
        foreach (TreeNode _node in this._fieldsTreeCache.Nodes)
        
            fieldsTree.Nodes.Add((TreeNode)_node.Clone());
        
    
    //enables redrawing tree after all objects have been added
    this.fieldsTree.EndUpdate();

【讨论】:

我也采用了这种方法,非常适合我的情况。 _treeTablesCache 是如何创建的? 如果我有一个具有多个节点级别的节点呢? @Thunder 你应该在表单类Form.Designer.cs 中定义它,就像这样private System.Windows.Forms.TreeView _fieldsTreeCache;。在 Form 构造函数 this._fieldsTreeCache = new TreeView(); 中启动它,并在添加或删除节点时填充它。或其他地方,如Form_Shown【参考方案2】:

这里有一个简单的小例子(带有来自 msdn 的代码),它是一种过滤掉 TreeView 节点显示的非常简单的方法。

winforms 在树形视图中只能添加或删除 TreeNode。

如果将节点与它们的数据一起存储到字典中(使用唯一键),则仍然可以改进对节点的搜索。

using System.Collections;
using System.Windows.Forms;

namespace FilterWinFormsTreeview

  // The basic Customer class.
  public class Customer : System.Object
  
    private string custName = "";
    protected ArrayList custOrders = new ArrayList();

    public Customer(string customername) 
      this.custName = customername;
    

    public string CustomerName 
      get  return this.custName; 
      set  this.custName = value; 
    

    public ArrayList CustomerOrders 
      get  return this.custOrders; 
    
  

  // End Customer class 

  // The basic customer Order class.
  public class Order : System.Object
  
    private string ordID = "";

    public Order(string orderid) 
      this.ordID = orderid;
    

    public string OrderID 
      get  return this.ordID; 
      set  this.ordID = value; 
    
  

  // End Order class

  public static class TreeViewHelper
  
    // Create a new ArrayList to hold the Customer objects.
    private static ArrayList customerArray = new ArrayList();

    public static void FilterTreeView(TreeView treeView1, string orderText) 
      if (string.IsNullOrEmpty(orderText)) 
        FillMyTreeView(treeView1);
       else 
        // Display a wait cursor while the TreeNodes are being created.
        Cursor.Current = Cursors.WaitCursor;

        // Suppress repainting the TreeView until all the objects have been created.
        treeView1.BeginUpdate();

        foreach (TreeNode customerNode in treeView1.Nodes) 
          var customer = customerNode.Tag as Customer;
          if (customer != null) 
            customerNode.Nodes.Clear();
            // Add a child treenode for each Order object in the current Customer object.
            foreach (Order order in customer.CustomerOrders) 
              if (order.OrderID.Contains(orderText)) 
                var orderNode = new TreeNode(customer.CustomerName + "." + order.OrderID);
                customerNode.Nodes.Add(orderNode);
              
            
          
        

        // Reset the cursor to the default for all controls.
        Cursor.Current = Cursors.Default;

        // Begin repainting the TreeView.
        treeView1.EndUpdate();
      
    

    public static void FillMyTreeView(TreeView treeView1) 
      // Add customers to the ArrayList of Customer objects.
      if (customerArray.Count <= 0) 
        for (int x = 0; x < 1000; x++) 
          customerArray.Add(new Customer("Customer" + x.ToString()));
        

        // Add orders to each Customer object in the ArrayList.
        foreach (Customer customer1 in customerArray) 
          for (int y = 0; y < 15; y++) 
            customer1.CustomerOrders.Add(new Order("Order" + y.ToString()));
          
        
      

      // Display a wait cursor while the TreeNodes are being created.
      Cursor.Current = Cursors.WaitCursor;

      // Suppress repainting the TreeView until all the objects have been created.
      treeView1.BeginUpdate();

      // Clear the TreeView each time the method is called.
      treeView1.Nodes.Clear();

      // Add a root TreeNode for each Customer object in the ArrayList.
      foreach (Customer customer2 in customerArray) 
        var customerNode = new TreeNode(customer2.CustomerName);
        customerNode.Tag = customer2;
        treeView1.Nodes.Add(customerNode);

        // Add a child treenode for each Order object in the current Customer object.
        foreach (Order order1 in customer2.CustomerOrders) 
          var orderNode = new TreeNode(customer2.CustomerName + "." + order1.OrderID);
          customerNode.Nodes.Add(orderNode);
        
      

      // Reset the cursor to the default for all controls.
      Cursor.Current = Cursors.Default;

      // Begin repainting the TreeView.
      treeView1.EndUpdate();
    
  

【讨论】:

with code from msdn,链接在哪里? @punker76【参考方案3】:

    TreeView 中的每个节点都有ExpandedIsVisible 属性。同时可见的项目数量是有限的(TreeView.VisibleCount)。根据这些信息,您可以显着减少要探测的节点数量。

    扫描节点及其子节点时,您可以在折叠节点内找到第一个匹配项时中止递归,因此您已经知道它至少有一个子节点并且无论如何都是可见的。

    李>

    异步执行过滤。 (例如使用new Task())在输入最少数量的字符后开始第一个任务(比如说3)。下一个键入的字符必须取消正在运行的任务并开始新的任务。

【讨论】:

在 c# winforms 中扩展文本框

】在c#winforms中扩展文本框【英文标题】:Extendtextboxinc#winforms【发布时间】:2021-11-2212:12:57【问题描述】:我一直在寻找这个问题的答案(我在c#中使用winforms)。我正在寻找图片中的控件,单击时带有向下箭头的文本框打开了扩... 查看详情

使用 C# Winforms 创建和打开临时文本文件

...述】:我有一个收集和编译数据并显示在表单上的winforms应用程序。我希望用户能够单击一个按钮,该按钮基本上将该数据导出到一个txt文件,他们可以在其中打印或保存文本文件。我知道usingStreamWritertxtFile=F 查看详情

C# Winform 文本框数值

...,我有一个表(Product)(Itemnvarchar(50),Pricereal)在我的C#winform应用程序中,我有一个该表的类对象classProductstringItem;doublePrice;usingbindingsource,Ibi 查看详情

C#如何在treeview控件winform的所有父子节点中搜索文本

】C#如何在treeview控件winform的所有父子节点中搜索文本【英文标题】:C#Howtosearchatextinallparent&childnodesoftreeviewcontrolwinform【发布时间】:2019-11-0602:53:48【问题描述】:我正在递归搜索所有treeview的父节点和子节点中的文本,但没... 查看详情

在 C# 中获取没有 Hotkey('&') 的标签文本

...布时间】:2017-06-0404:54:00【问题描述】:在我的C#Winforms应用程序中,我几乎没有设置热键的标签控件。(例如:&Name)。我们正在使用JAWS屏幕阅读器。Labe 查看详情

在启动 C# .NET 时将文本加载到文本框中

...我不知道这应该如何工作。我有一个带有文本框的WinForm应用程序,当我在其中写一些东西并关闭winform时,它并没有保存它(显然)如何让它保存我在文本框中输入的文本,然后当我打开WinForm应用程序时,它会保存文 查看详情

使用 PostgreSql 和 ADO.NET 在 C# WinForms 中锁定记录和表

...work4.6.1、WinForms、PostgreSQL6.4beta4和Npgsql和ADO.NET。我当前的应用程序是一个多用户应用程序 查看详情

是否可以在 C# winforms 中一次将文本写入多个文本框?

】是否可以在C#winforms中一次将文本写入多个文本框?【英文标题】:IsitpossibletowriteatextontomultipletextboxesatonceinC#winforms?【发布时间】:2021-09-0202:14:14【问题描述】:是否可以一次将文本写入多个文本框(参见代码)?除了一次将... 查看详情

如何在 C# 控制台或 WinForms 应用程序中使用 Windows 安全的确认证书弹出窗口选择证书?

】如何在C#控制台或WinForms应用程序中使用Windows安全的确认证书弹出窗口选择证书?【英文标题】:HowtoselectaCertificateusingtheWindowsSecurity\'sConfirmCertificatepopupinC#consoleorWinFormsapplication?【发布时间】:2020-07-0922:56:26【问题描述】:我... 查看详情

在 C# winform 中使用 app.config 访问数据库连接字符串

...2012-01-1813:15:33【问题描述】:我似乎无法在我的c#winforms应用程序中访问app.config数据库连接字符串。app.config代码<connectionStrings><add 查看详情

SQL注入在winforms中有效吗?

...经阅读了有关sql-injection的信息,但我没有发现它在我的应用程序上运行。SQL注入在winforms中有效吗?如果是,如何防止它们。编辑:我正在使用文本框来读取用户名和密码。通过使用textboxex,我发现 查看详情

在 C# Winforms 应用程序中键入时如何搜索 SQL Server 数据库?

】在C#Winforms应用程序中键入时如何搜索SQLServer数据库?【英文标题】:HowcanisearchSQLServerDatabasewhiletypinginC#Winformsapplication?【发布时间】:2019-12-2710:04:19【问题描述】:我在winforms应用程序的数据网格视图中显示了一些sql表结果。... 查看详情

如何在Winforms,C#中为文本框添加千位分隔符[重复]

】如何在Winforms,C#中为文本框添加千位分隔符[重复]【英文标题】:HowtoaddathousandseparatorforatextboxinWinforms,C#[duplicate]【发布时间】:2021-04-1322:33:44【问题描述】:我想知道如何在我的文本框中输入数字时添加千位分隔符,例如逗... 查看详情

从 WinForm C# 在 WhatsApp 桌面聊天中添加文件

...:最近怎么样?我想看看是否可以在C#中附加来自WinForms应用程序的文件并将其发送到WhatsApp桌面。要启动WhatsApp桌面应用程序,我使用以下命令:varprocess=$"whatsapp://send?ph 查看详情

VS2019 WinForms 在诊断工具中没有显示任何事件

...20-01-0900:11:19【问题描述】:我尝试使用WinForms创建简单的应用程序。使用设计器,我添加了几个按钮文本字段等。没有C#代码修改,只能拖放到布局。但是,在运行应用程序时,按钮单击或任何其他操作不会显示任何事件。我正... 查看详情

C# - Winforms - Combobox - 避免选择更新数据源的第一项

...atasource【发布时间】:2022-01-0815:59:27【问题描述】:我的应用程序中有一个组合框,根据您可以在文本字段中输入的搜索文本,异步加载项目。这工作正常,但每次在更新组合框的数据源期间自动选择第一项的文本。这会导致意... 查看详情

如何在 .NET 4.0 C# WinForms 应用程序中播放 SWF 文件?

】如何在.NET4.0C#WinForms应用程序中播放SWF文件?【英文标题】:HowtoplaySWFfilein.NET4.0C#WinFormsapplication?【发布时间】:2014-06-2007:54:25【问题描述】:我有一个SWF文件,我希望它也可以离线使用。我已经搜索了如何播放SWF文件。但是... 查看详情

c# winforms如何保存用户输入的数据

...就像他们在文本框中键入或选中复选框并在下次再次启动应用程序时关闭应用程序一样,他们输入的数据就像已保存一样。这是在c#VS2010.NET4.0中【问题讨论】:最好说明您要保存它的位置,即sql数据库、.config用 查看详情