Как заставить Treeview проверять только один вариант - PullRequest
2 голосов
/ 05 октября 2011

У меня есть древовидная структура, и флажок установлен в true. Я хочу, чтобы во всем древовидном меню был выбран только один флажок. Как я могу это сделать?

К вашему сведению: дерево имеет три уровня глубины.

Ответы [ 7 ]

3 голосов
/ 05 октября 2011

Самый простой способ сделать это - установить четный обработчик для события 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;
            }
        }
    }
}

Должен работать (не пробовал)

1 голос
/ 27 мая 2016

Это старый пост, хотя ни одно из предложенных решений не работает в моем случае.

Итак, я сделал следующее:

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!

надежда, полезная для других

0 голосов
/ 21 января 2019

Это решение , которое я беззастенчиво похитил, позволяет перебирать все узлы на всех уровнях за один раз.

Это упрощает выбор только одного узла:

    foreach (var node in resultsTree.GetAllNodes())
    {
        if (node != e.Node) node.Checked = false;
    }
0 голосов
/ 23 мая 2018

У меня была та же проблема, но зацикливание на всех узлах звучит дорого для производительности.

Вот мое решение без зацикливания всех узлов, но с использованием свойства класса:

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"
                    }
    }

}

Единственная проблема, которую я обнаружил в этом решении, заключается в том, что если пользователь переключает один и тот же флажок на быстрый, функция не вызывается правильно и не «ставит» или «снимает» флажок одним щелчком, сразу после нажатия тогда дважды.

Может быть, кто-то еще может добавить исправление для того же флажка, чтобы быстро во время выполнения.

0 голосов
/ 14 февраля 2017

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>
0 голосов
/ 29 мая 2015

Я пробовал, конечно, работает

       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;
            }
0 голосов
/ 05 октября 2011

Я использую найденное решение здесь .

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)");
 }

ПРИМЕЧАНИЕ: прочитайте мой пост Как заставить javascript работать вместе с Ajax UpdatePanel , если TreeView находится внутри UpdatePanel

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...