2012-06-13 64 views
1

這就是我要實現的功能:TreeView的功能,取消所有其他節點

  1. 檢查通過點擊鼠標樹節點爲正常,用戶可以多選。

  2. 當用戶按住Ctrl +鼠標時,我想要檢查鼠標點擊的樹節點,並且所有其他節點都未被選中。

我有一個版本,但它是不優雅:

有什麼建議?

如果要測試代碼,請將TreeViewAdv和TreeNodeAdv替換爲普通的TreeView和TreeNode。

using Syncfusion.Windows.Forms.Tools; 

namespace treeviewtest 
{ 
    public partial class Form1 : Form 
    { 
     TreeNodeAdv CurrentNode = null; 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void treeViewAdv1_AfterCheck(object sender, Syncfusion.Windows.Forms.Tools.TreeNodeAdvEventArgs e) 
     { 
      TreeViewAdv tree = sender as TreeViewAdv; 
      if (Control.ModifierKeys == Keys.Control 
        && e.Action!= TreeViewAdvAction.Unknown) 
      { 

       foreach (TreeNodeAdv node in tree.Nodes) 
       { 
        if (node.CheckState == CheckState.Checked && node != CurrentNode) 
         node.Checked = false; 

        foreach (TreeNodeAdv n in node.WalkTree()) 
        { 
         if (n.CheckState == CheckState.Checked && n != CurrentNode) 
          n.Checked = false; 
        } 
       } 
      } 
      CurrentNode = null; 
     } 

     private void treeViewAdv1_BeforeCheck(object sender, TreeNodeAdvBeforeCheckEventArgs e) 
     { 
      if (Control.ModifierKeys == Keys.Control && CurrentNode == null) 
      { 
       CurrentNode = e.Node; 
       if (e.NewCheckState == CheckState.Unchecked) 
       { 
        TreeViewAdv tree = sender as TreeViewAdv; 
        foreach (TreeNodeAdv node in tree.Nodes) 
        { 
         if (node.CheckState == CheckState.Checked && node != CurrentNode) 
          node.Checked = false; 

         foreach (TreeNodeAdv n in node.WalkTree()) 
         { 
          if (n.CheckState == CheckState.Checked && n != CurrentNode) 
           n.Checked = false; 
         } 
        } 
        e.Cancel = true; 
       } 
      } 
     } 
    } 

    public static class externtree 
    { 
     public static IEnumerable<TreeNodeAdv> WalkTree(this TreeNodeAdv node) 
     { 
      if (node == null) 
       yield break; 

      // return itself first 
      yield return node; 

      // return children 
      if (node.HasChildren) 
      { 
       foreach (TreeNodeAdv cNode in node.Nodes) 
        foreach (TreeNodeAdv iNode in cNode.WalkTree()) 
         yield return iNode; 
      } 
     } 
    } 
} 

回答

2

讓它優雅,繼承和遞歸:

using System; 
using System.Windows.Forms; 

class MyTreeView : TreeView { 
    protected override void OnAfterCheck(TreeViewEventArgs e) { 
     if (checking) return; 
     checking = true; 
     if (e.Node.Checked && (Control.ModifierKeys & Keys.Control) == Keys.Control) { 
      uncheckNodes(this.Nodes, e.Node); 
     } 
     checking = false; 
     base.OnAfterCheck(e); 
    } 

    private void uncheckNodes(TreeNodeCollection nodes, TreeNode except) { 
     foreach (TreeNode node in nodes) { 
      if (node != except) node.Checked = false; 
      uncheckNodes(node.Nodes, except); 
     } 
    } 
    private bool checking; 
} 
+0

THX,和一點點不同的是,在「Ctrl」鍵模式時,我的要求會令檢查,即使它是從檢查未選中的節點。我只是添加一個e.Node.Checked = true;就在檢查= false之前; Thx再次。 – ArdenZhao

相關問題