TreeView Node rekursiv über String suchen

/// <summary->
/// sucht TreeNode rekursiv
/// </summary->
/// <param name=&quot;n&quot;->StartNode</param->
/// <param name=&quot;txt&quot;->Suchtext</param->
/// <returns->gefundene TreeNode oder null</returns->
public TreeNode FindNode(TreeNode n, string txt)
{
    TreeNode r = null;

    foreach (TreeNode tn in n.Nodes)
    {
        if (tn.Text == txt)
        {
            r = tn;
            break;
        }

        r = FindNode(tn, txt);

        if (r != null) break;
    }

    return r;
}

Verhindern, dass TreeNode bei Rechtsklick deselektiert wird

Oft kommt es vor, dass man in einem TreeView eine TreeNode per Rechtsklick selektiert, zum Beispiel beim gleichzeitigen Anzeigen eines ContextMenueStrips. Dabei “schnappt” meist die Auswahl wieder auf die zuvor ausgewählte TreeNode zurück und das falsche Element ist gewählt. Um das zu verhindern muss man folgenden Code implementieren:

private void TreeView1_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        TreeNode tnd = TreeView1.GetNodeAt(e.X, e.Y);
        if (tnd != null)
        {
            TreeView1.SelectedNode = tnd;
        }
    }
}

Drag und Drop innerhalb eines TreeViews

  • im Beispiel wird eine TreeNode innerhalb des TreeViews verschoben
  • als erstes ist das Ereignis ItemDrag zu behandeln:
private void TreeView1_ItemDrag(object sender, ItemDragEventArgs e)
{
    TreeView tv = sender as TreeView;

    if (tv != null)
    {
        if (tv.SelectedNode != null)
        {
            tv.DoDragDrop(tv.SelectedNode, DragDropEffects.Copy);
        }
    }
}
  • beim TreeView muss die Eigenschaft AllowDrop = True gesetzt sein
  • zusätzlich sind die Ereignisse DragOver und DragDrop zu behandeln:
private void TreeView1_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.None;

    // Quellnode
    TreeNode tns = e.Data.GetData(typeof(TreeNode)) as TreeNode;
    // akt. Zielnode unter dem Mauspfeil
    TreeNode tnd = TreeView1.GetNodeAt(TreeView1.PointToClient(new Point(e.X, e.Y)));

    if ((tns != null) && (tnd != null))
    {
        // hier im Beispiel die Verschiebung nur zulassen, wenn ChildNodes (Level == 1)
        // auf andere Parent-/Rootnodes (Level == 0) gezogen werden.
        if ((TreeView1.SelectedNode.Level == 1) && (tnd.Level == 0) && (tnd != tns.Parent))
        {
            e.Effect = DragDropEffects.Copy;
        }
    }
}

private void TreeView1_DragDrop(object sender, DragEventArgs e)
{
    // Quellnode
    TreeNode tns = e.Data.GetData(typeof(TreeNode)) as TreeNode;
    // akt. Zielnode unter dem Mauspfeil
    TreeNode tnd = TreeView1.GetNodeAt(TreeView1.PointToClient(new Point(e.X, e.Y)));

    if ((tns != null) && (tnd != null))
    {
        // neue TreeNode aus Clone der Quellnode erstellen
        TreeNode tnnew = (TreeNode)tns.Clone();
        tnd.Nodes.Add(tnnew);
        tnd.Expand();

        // alte Quell-TreeNode entfernen
        TreeNode cat = tns.Parent;
        cat.Nodes.Remove(tns);
    }
}