如何让Treeview只勾选一个选项

发布于 2024-12-08 04:34:57 字数 83 浏览 0 评论 0原文

我有一个树视图,并且复选框设置为 true。我想要的是整个树视图中只选择一个复选框。我怎样才能做到这一点?

仅供参考:树视图有三层深度。

I have a treeview and Checkbox is set true. What I want is that only one checkbox is selected in the whole treeview. How can I do that?

FYI: the treeview is in three level depth.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

清风不识月 2024-12-15 04:34:58

我遇到了同样的问题,但循环所有节点听起来对性能来说代价高昂。

这是我的解决方案,没有循环遍历所有节点,而是使用类属性:

public partial class GuiDefault // not my whole class, just an example
{ 

TreeNode checkedNode = null;

    private void Tree_AfterCheck(object sender, TreeViewEventArgs e)
    {
        TreeNode checkedNodeVar = e.Node;

        if (checkedNodeVar.Checked)
                    {

                        if (checkedNode != null)
                        {
                            checkedNode.Checked = false; // set "checked" property of the last checked box to false
                        }

                        checkedNode = checkedNodeVar; // set the class property "checkedNode" to the currently checked Node
                    }
        else
                    {
                        checkedNode = null; // if current checked box gets unchecked again, also reset the class property "checkedNode"
                    }
    }

}

我发现此解决方案的唯一问题是,如果用户将同一复选框切换为快速,则该函数不会被正确调用,并且不会“检查”或者单击两次后单击一次“取消选中”该框。

也许其他人可以添加修复程序,以在运行时快速单击同一复选框。

I had the same issue, but looping trough all Nodes sounds expensive for performance.

Here is my solution without looping trough all Nodes, but using a class property:

public partial class GuiDefault // not my whole class, just an example
{ 

TreeNode checkedNode = null;

    private void Tree_AfterCheck(object sender, TreeViewEventArgs e)
    {
        TreeNode checkedNodeVar = e.Node;

        if (checkedNodeVar.Checked)
                    {

                        if (checkedNode != null)
                        {
                            checkedNode.Checked = false; // set "checked" property of the last checked box to false
                        }

                        checkedNode = checkedNodeVar; // set the class property "checkedNode" to the currently checked Node
                    }
        else
                    {
                        checkedNode = null; // if current checked box gets unchecked again, also reset the class property "checkedNode"
                    }
    }

}

The only issue i found with this solution is that if the user toggle the same checkbox to fast, the function doesn't get called correctly and it doesnt "check" or "uncheck" the box with 1 click, just after clicking it twice then.

Maybe someone else can add a fix for clicking the same checkbox to fast at runtime.

泛泛之交 2024-12-15 04:34:58
// Upon node checked, uncheck all other nodes
private void tvAccountHierarchy_AfterCheck(object sender, TreeViewEventArgs e)
    {
        // only do it if the node became checked:
        if (e.Node.Checked)
        {   
            Uncheck_Treenodes(e.Node.TreeView.Nodes, e.Node);                
        }
    }

//Recursively iterate through all child nodes and uncheck all except the checkedNode
 private void Uncheck_Treenodes(TreeNodeCollection treeNodes, TreeNode checkedNode)
    {            
        // iterate through child nodes & uncheck
        foreach (TreeNode cur_node in treeNodes)
        {
            if (cur_node != checkedNode)
            {
                // ... uncheck them
                cur_node.Checked = false;
            }
            Uncheck_Treenodes(cur_node.Nodes, checkedNode);
        }
    }
// Upon node checked, uncheck all other nodes
private void tvAccountHierarchy_AfterCheck(object sender, TreeViewEventArgs e)
    {
        // only do it if the node became checked:
        if (e.Node.Checked)
        {   
            Uncheck_Treenodes(e.Node.TreeView.Nodes, e.Node);                
        }
    }

//Recursively iterate through all child nodes and uncheck all except the checkedNode
 private void Uncheck_Treenodes(TreeNodeCollection treeNodes, TreeNode checkedNode)
    {            
        // iterate through child nodes & uncheck
        foreach (TreeNode cur_node in treeNodes)
        {
            if (cur_node != checkedNode)
            {
                // ... uncheck them
                cur_node.Checked = false;
            }
            Uncheck_Treenodes(cur_node.Nodes, checkedNode);
        }
    }
情仇皆在手 2024-12-15 04:34:58

我使用此处找到的解决方案。

页面中的 javascript

function client_OnTreeNodeChecked(event)
{
 var treeNode = event.srcElement || event.target ;
 if (treeNode.tagName == "INPUT" && treeNode.type == "checkbox")
  {
   if(treeNode.checked)
    {
     uncheckOthers(treeNode.id);
    }
  }
}

function uncheckOthers(id)
 {
  var elements = document.getElementsByTagName('input');
  // loop through all input elements in form
  for(var i = 0; i < elements.length; i++)
   {
    if(elements.item(i).type == "checkbox")
    {
     if(elements.item(i).id!=id)
     {
      elements.item(i).checked=false;
     }
    }
   }
  }

和代码后面将 client_OnTreeNodeChecked 函数添加到树视图 onclick 事件

private void Page_PreRender(object sender, EventArgs e)
 {
  TreeView1.Attributes.Add("OnClick", "client_OnTreeNodeChecked(event)");
 }

注意:阅读我的帖子 如果 TreeView 位于更新面板

I use the solution found here.

A javascript in the page

function client_OnTreeNodeChecked(event)
{
 var treeNode = event.srcElement || event.target ;
 if (treeNode.tagName == "INPUT" && treeNode.type == "checkbox")
  {
   if(treeNode.checked)
    {
     uncheckOthers(treeNode.id);
    }
  }
}

function uncheckOthers(id)
 {
  var elements = document.getElementsByTagName('input');
  // loop through all input elements in form
  for(var i = 0; i < elements.length; i++)
   {
    if(elements.item(i).type == "checkbox")
    {
     if(elements.item(i).id!=id)
     {
      elements.item(i).checked=false;
     }
    }
   }
  }

And code behind to add client_OnTreeNodeChecked function to your treeviews onclick event

private void Page_PreRender(object sender, EventArgs e)
 {
  TreeView1.Attributes.Add("OnClick", "client_OnTreeNodeChecked(event)");
 }

NOTE: read my post How to make javascript work along with Ajax UpdatePanel if TreeView is inside an UpdatePanel

天涯离梦残月幽梦 2024-12-15 04:34:58

此解决方案我无耻地偷来的它允许您一次性迭代所有级别的所有节点。

这使得确保只选择一个节点变得容易:

    foreach (var node in resultsTree.GetAllNodes())
    {
        if (node != e.Node) node.Checked = false;
    }

This solution which I shamelessly stole allows you to iterate over all nodes at all levels in one go.

This makes ensuring only one node is selected easy:

    foreach (var node in resultsTree.GetAllNodes())
    {
        if (node != e.Node) node.Checked = false;
    }
不离久伴 2024-12-15 04:34:58

输入图片此处描述

        <script type="text/javascript">

    function MakeRadio() {
        var tv = document.getElementById("<%= position_TreeView.ClientID %>");
        var chkArray = tv.getElementsByTagName("input");

        for (i = 0; i <= chkArray.length - 1; i++) {
            if (chkArray[i].type == 'checkbox') {
                chkArray[i].type = 'radio';
                chkArray[i].name = 'YaMahdi';
            }
        }
    }

    window.onload = MakeRadio;

</script>
    <script type="text/javascript">

    function OnTreeClick(evt) {
        var src = window.event != window.undefined ? window.event.srcElement : evt.target;
        var isChkBoxClick = (src.tagName.toLowerCase() == "input" && src.type == "radio");
        if (isChkBoxClick) {
            SelectOne(src.id);
        }
    }


    function SelectOne(objId) {
        var tv = document.getElementById("<%= position_TreeView.ClientID %>");
        var chkArray = tv.getElementsByTagName("input");

        for (i = 0; i <= chkArray.length - 1; i++) {
            if (chkArray[i].type == 'radio') {
                if (chkArray[i].id != objId) {
                    chkArray[i].checked = false;
                }
            }
        }
    }
</script>

enter image description here

        <script type="text/javascript">

    function MakeRadio() {
        var tv = document.getElementById("<%= position_TreeView.ClientID %>");
        var chkArray = tv.getElementsByTagName("input");

        for (i = 0; i <= chkArray.length - 1; i++) {
            if (chkArray[i].type == 'checkbox') {
                chkArray[i].type = 'radio';
                chkArray[i].name = 'YaMahdi';
            }
        }
    }

    window.onload = MakeRadio;

</script>
    <script type="text/javascript">

    function OnTreeClick(evt) {
        var src = window.event != window.undefined ? window.event.srcElement : evt.target;
        var isChkBoxClick = (src.tagName.toLowerCase() == "input" && src.type == "radio");
        if (isChkBoxClick) {
            SelectOne(src.id);
        }
    }


    function SelectOne(objId) {
        var tv = document.getElementById("<%= position_TreeView.ClientID %>");
        var chkArray = tv.getElementsByTagName("input");

        for (i = 0; i <= chkArray.length - 1; i++) {
            if (chkArray[i].type == 'radio') {
                if (chkArray[i].id != objId) {
                    chkArray[i].checked = false;
                }
            }
        }
    }
</script>
不奢求什么 2024-12-15 04:34:57

最简单的方法是为树视图的 AfterCheck 事件设置一个偶数处理程序。在此处理程序中,您可以取消选中所有节点,但刚刚选中的节点除外:

void node_AfterCheck(object sender, TreeViewEventArgs e) {
    // only do it if the node became checked:
    if (e.Node.Checked) {
        // for all the nodes in the tree...
        foreach (TreeNode cur_node in e.Node.TreeView.Nodes) {
            // ... which are not the freshly checked one...
            if (cur_node != e.Node) {
                // ... uncheck them
                cur_node.Checked = false;
            }
        }
    }
}

应该可以工作(没有尝试)

The simplest way to do that is to set an even handler to your tree view's AfterCheck event. In this handler you can uncheck all the nodes but the one which just became checked:

void node_AfterCheck(object sender, TreeViewEventArgs e) {
    // only do it if the node became checked:
    if (e.Node.Checked) {
        // for all the nodes in the tree...
        foreach (TreeNode cur_node in e.Node.TreeView.Nodes) {
            // ... which are not the freshly checked one...
            if (cur_node != e.Node) {
                // ... uncheck them
                cur_node.Checked = false;
            }
        }
    }
}

Should work (didn't try)

浅听莫相离 2024-12-15 04:34:57

这是一篇旧文章,尽管提供的解决方案都不适用于我的情况。

所以我做了如下操作,

private TreeNode uncheck_treeview(TreeView treeView, TreeNode treeNode, TreeViewEventHandler e)
{
    treeView.AfterCheck -= e;

    foreach (TreeNode node in treeView.Nodes)
    {
        uncheck_treenode_tree(node);
    }

    if (treeNode != null)
    {
        treeNode.Checked = true;
    }

    treeView.AfterCheck += e;

    return treeNode;
}

private void uncheck_treenode(TreeNode treeNode)
{
    treeNode.Checked = false;
    foreach (TreeNode node in treeNode.Nodes)
    {
        uncheck_treenode_tree(node);
    }
}

注意

private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
    var checkedNode = uncheck_treeview_tree((TreeView) sender, e.Node, treeView1_AfterCheck);
    // further processing ...
}

此方法可以防止 StackOverflowException

希望对其他人有用

It is an old post, though none of provided solutions is working in my case.

So I did as follows,

private TreeNode uncheck_treeview(TreeView treeView, TreeNode treeNode, TreeViewEventHandler e)
{
    treeView.AfterCheck -= e;

    foreach (TreeNode node in treeView.Nodes)
    {
        uncheck_treenode_tree(node);
    }

    if (treeNode != null)
    {
        treeNode.Checked = true;
    }

    treeView.AfterCheck += e;

    return treeNode;
}

and

private void uncheck_treenode(TreeNode treeNode)
{
    treeNode.Checked = false;
    foreach (TreeNode node in treeNode.Nodes)
    {
        uncheck_treenode_tree(node);
    }
}

and

private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
    var checkedNode = uncheck_treeview_tree((TreeView) sender, e.Node, treeView1_AfterCheck);
    // further processing ...
}

note that this method prevents StackOverflowException !

hope useful to others

暮光沉寂 2024-12-15 04:34:57

我试过了,确实有效

       bool manualcheck = false;
      protected override void OnAfterCheck(TreeViewEventArgs e)
      {
                if (manualcheck) return;
                if (e.Node.Checked)
                {
                   if (Nodes.Count>0) UnCheckAll(Nodes[0]);
                   manualcheck = true;
                e.Node.Checked = true;
                manualcheck = false;
                }


        }


        void UnCheckAll(TreeNode node)
            {


                if (node != null)
                {

                    node.Checked = false;
                    foreach (TreeNode item in node.Nodes)
                    {
                        manualcheck = true;
                        item.Checked = false;
                        if (item.Nodes.Count > 0) UnCheckAll(item.Nodes[0]);
                    }


                    if (node.NextNode != null)
                        UnCheckAll(node.NextNode);

                }
                manualcheck = false;
            }

I tried it certainly works

       bool manualcheck = false;
      protected override void OnAfterCheck(TreeViewEventArgs e)
      {
                if (manualcheck) return;
                if (e.Node.Checked)
                {
                   if (Nodes.Count>0) UnCheckAll(Nodes[0]);
                   manualcheck = true;
                e.Node.Checked = true;
                manualcheck = false;
                }


        }


        void UnCheckAll(TreeNode node)
            {


                if (node != null)
                {

                    node.Checked = false;
                    foreach (TreeNode item in node.Nodes)
                    {
                        manualcheck = true;
                        item.Checked = false;
                        if (item.Nodes.Count > 0) UnCheckAll(item.Nodes[0]);
                    }


                    if (node.NextNode != null)
                        UnCheckAll(node.NextNode);

                }
                manualcheck = false;
            }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文