2009-11-02 27 views
9

¿Cuál es la forma mejor/más eficiente de filtrar los nodos Treeview utilizando WinForms.TreeView?WinForms.TreeView: la mejor forma de filtrar nodos

Por ejemplo: escribí "abc" y solo los Nodos que contenían "abc" se hicieron visibles. Luego escribí "abcd" y debería ver los únicos nodos que contenían el texto "abcd". Y así sucesivamente, así que cada vez que cambio el criterio de filtro, el contenido de la vista de árbol también cambia.

¿Alguna idea?

- mejores deseos, Murat

Respuesta

10

Si usted está buscando el mejor rendimiento, clonar el árbol, a continuación, quitar todos los elementos del árbol clonado, a continuación, sólo tiene que sustituir el árbol existente con el clonado (y filtrado) uno.

También tengo un árbol de respaldo que siempre está sin filtrar.

Esto funciona bien para árboles bastante grandes con 1000 - 2000 nodos.

+0

Estoy de acuerdo con este enfoque, no es un patrón relacionado con él llama el patrón de recuerdo. – Burt

+3

No es bonito, hubiera sido mucho mejor tener una propiedad 'Visible' en un TreeNode. – leppie

+0

Voy a probar este método. Gracias por el consejo. Planeo implementar esta característica en TreeView con hasta 10-20k nodos ... –

0

Si pasa de una hoja a otra, puede encontrar los nodos raíz que no contienen ninguna coincidencia de la cadena en sus hojas.

0

heredo TreeView para filtrarlo (sólo para el primer nivel, estoy trabajando en él):

public partial class winTree : TreeView 
{ 
    private NodesCollection allNodes = new NodesCollection(); 

    [ReadOnly(true)] 
    public new NodesCollection Nodes { get { return allNodes; } } 

    private string filtro = string.Empty; 
    public String Filtro 
    { 
     get { return filtro; } 
     set { filtro = value; filtrarNodos(); } 
    } 

    public winTree() 
    { 
     InitializeComponent(); 

     allNodes.NodeAdd += OnNodeAdd; 
     allNodes.NodeRemove += OnNodeRemove; 
     allNodes.NodesClear += OnNodesClear; 
    } 


    private void OnNodeAdd(object sender, EventArgs e) 
    { 
     TreeNode n = (TreeNode)sender; 

     if (passFilter(n)) 
     { 
      base.Nodes.Add(n); 
     } 
    } 

    private void OnNodeRemove(object sender, EventArgs e) 
    { 
     base.Nodes.Remove((TreeNode)sender); 
    } 

    private void OnNodesClear(object sender, EventArgs e) 
    { 
     base.Nodes.Clear(); 
    } 


    private void filtrarNodos() 
    { 
     this.BeginUpdate(); 

     base.Nodes.Clear(); 

     foreach(TreeNode n in this.Nodes) 
     { 
      if (passFilter(n)) 
      { 
       base.Nodes.Add(n); 
      } 
     } 

     this.EndUpdate(); 
    } 

    private bool passFilter(TreeNode nodo) 
    { 
     if (string.IsNullOrWhiteSpace(filtro)) 
     { 
      return true; 
     } 
     else 
     { 
      return nodo.Text.ToLower().Contains(filtro.ToLower()); 
     } 
    } 
} 

public class NodesCollection : IList<TreeNode> 
{ 
    private List<TreeNode> nodos = new List<TreeNode>(); 

    public event EventHandler NodeAdd; 
    public event EventHandler NodeRemove; 
    public event EventHandler NodesClear; 

    private void OnNodeAdd(TreeNode nodo) 
    { 
     if (NodeAdd != null) 
     { 
      NodeAdd(nodo, EventArgs.Empty); 
     } 
    } 

    private void OnNodeRemove(TreeNode nodo) 
    { 
     if (NodeRemove != null) 
     { 
      NodeRemove(nodo, EventArgs.Empty); 
     } 
    } 

    private void OnNodesClear() 
    { 
     if (NodeRemove != null) 
     { 
      NodesClear(this, EventArgs.Empty); 
     } 
    } 


    #region IList<TreeNode> 

     public int IndexOf(TreeNode item) 
     { 
      return nodos.IndexOf(item); 

      OnNodeAdd(item); 
     } 

     public void Insert(int index, TreeNode item) 
     { 
      nodos.Insert(index, item); 

      OnNodeAdd(item); 
     } 

     public void RemoveAt(int index) 
     { 
      TreeNode nodo = nodos[index]; 

      nodos.RemoveAt(index); 

      OnNodeRemove(nodo); 
     } 

     public TreeNode this[int index] 
     { 
      get 
      { 
       return nodos[index]; 
      } 
      set 
      { 
       OnNodeRemove(nodos[index]); 
       nodos[index] = value; 
       OnNodeAdd(nodos[index]); 
      } 
     } 

     public void Add(TreeNode item) 
     { 
      nodos.Add(item); 

      OnNodeAdd(item); 
     } 

     public void Clear() 
     { 
      nodos.Clear(); 

      OnNodesClear(); 
     } 

     public bool Contains(TreeNode item) 
     { 
      return nodos.Contains(item); 
     } 

     public void CopyTo(TreeNode[] array, int arrayIndex) 
     { 
      nodos.CopyTo(array, arrayIndex); 
     } 

     public int Count 
     { 
      get { return nodos.Count(); } 
     } 

     public bool IsReadOnly 
     { 
      get { return true; } 
     } 

     public bool Remove(TreeNode item) 
     { 
      bool res = nodos.Remove(item); 

      if (res) 
      { 
       OnNodeRemove(item); 
      } 

      return res; 
     } 

     public IEnumerator<TreeNode> GetEnumerator() 
     { 
      return nodos.GetEnumerator(); 
     } 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      return nodos.GetEnumerator(); 
     } 

    #endregion 
} 
Cuestiones relacionadas