Как перебрать все слои узлов Treeview?

Сначала прочитайте РЕДАКТИРОВАТЬ 2

Я пытаюсь настроить способ визуально различать узлы в приложении winform. Например, чередование цветов.

Может ли кто-нибудь направить меня по этому пути? Кроме того, кто-нибудь еще должен был сделать это раньше и как вы это сделали?

Спасибо

РЕДАКТИРОВАТЬ

Я также видел настройку заднего цвета (спасибо), но у меня возникли проблемы с ее работой. Я не вижу события Paint() для древовидных представлений. Я попытался поместить приведенный ниже код в мою форму Load(), но он не работает. Возможно, потому что древовидная структура еще не загружена??

        private void frmCaseNotes_Load(object sender, System.EventArgs e)
    {
        foreach (TreeNode treeNode in treeView1.Nodes[0].Nodes)
        {
            treeNode.BackColor = Color.DeepSkyBlue;
        }
    }

РЕДАКТИРОВАТЬ 2

Хорошо, у меня есть первоначальная проблема, используя приведенное ниже в Form_Load()

            foreach (TreeNode treeNode in treeView1.Nodes)
        {
            if (treeNode.Index % 2 == 0)
            {
                 treeNode.ForeColor = Color.DodgerBlue;
            }
            else
            {
                treeNode.ForeColor = Color.Goldenrod;
            }

Теперь мне нужно выяснить, с чьей-то помощью, как перебрать ВСЕ слои узлов и применить мою чередующуюся окраску. Если я сделаю что-нибудь из приведенных ниже строк, я смогу достичь этого.

            foreach (TreeNode treeNode in treeView1.Nodes[1].Nodes[0].Nodes)
        {
            if (treeNode.Index % 2 == 0)
            {
                 treeNode.ForeColor = Color.DodgerBlue;
            }
            else
            {
                treeNode.ForeColor = Color.Goldenrod;
            }

Как программно перебрать ВСЕ слои?


person Refracted Paladin    schedule 08.04.2009    source источник
comment
Пока у вас есть дочерние узлы под одним корневым узлом, уже загруженным в элемент управления, ваш код должен работать.   -  person jgallant    schedule 08.04.2009


Ответы (5)


Рекурсия?

Изменить: добавлен код для устранения повторения цветов

protected void ColorNodes(TreeNode root, Color firstColor, Color secondColor)
{
   Color nextColor;
   foreach (TreeNode childNode in root.Nodes)
   {     
      nextColor = childNode.ForeColor = childNode.Index % 2 == 0 ? firstColor : secondColor;

      if (childNode.Nodes.Count > 0)
      {
         // alternate colors for the next node
         if (nextColor == firstColor)
              ColorNodes(childNode, secondColor, firstColor);
         else
              ColorNodes(childNode, firstColor, secondColor);
      }
   }
}

  private void frmCaseNotes_Load(object sender, System.EventArgs e)
    {
       foreach (TreeNode rootNode in treeView1.Nodes)
       {
          ColorNodes(rootNode, Color.Goldenrod, Color.DodgerBlue);
       }
    }
person Mike Marshall    schedule 08.04.2009
comment
Близко, спасибо! Он работает отлично, ЗА ИСКЛЮЧЕНИЕМ, что он пропускает окрашивание первого (корневого) слоя. - person Refracted Paladin; 09.04.2009
comment
Это достаточно близко, чтобы считать. Я разберусь с остальным и опубликую здесь для архивных целей. Спасибо за помощь! - person Refracted Paladin; 09.04.2009

Лучший способ сделать это — переопределить событие OnPaint и предоставить собственный код для рисования в элементе управления.

Вы можете найти множество примеров переопределения метода onPaint в Интернете.

РЕДАКТИРОВАТЬ: я на самом деле еще немного изучил это, и вы уже можете установить BackColor узлов дерева по отдельности.

Me.TreeView1.Nodes(0).BackColor = Color.AliceBlue  
person jgallant    schedule 08.04.2009

Чувак, с этим были серьезные проблемы. Широкий поиск был легким, но вы были правы. Глубинный поиск был болью. Я надеюсь, что это поможет вам. Жаль, что такой милый трюк, вероятно, канет в лету из-за огромного количества вопросов на этом сайте. Алгоритм глубины довольно грубый и предполагает головной узел без братьев и сестер.

//depth search on TreeView

TreeNode node = trv.Nodes[0];
Stack<TreeNode> list = new Stack<TreeNode>();
list.Push(node);

while (list.Count > 0)
{
    while (node.Nodes.Count > 0)
    {
        list.Push(node.Nodes[0]);
        node = node.Nodes[0];
    }

    //Will always have a leaf here as the current node. The leaf is not pushed.
    //If it has a sibling, I will try to go deeper on it.
    if (node.NextNode != null)
    {
        node = node.NextNode;
        continue;
    }

    //If it does NOT have a sibling, I will pop as many parents I need until someone
    //has a sibling, and go on from there.
    while (list.Count > 0 && node.NextNode == null)
    {
        node = list.Pop();
    }
    if (node.NextNode != null) node = node.NextNode;
}

//broadth search on TreeView

Queue<TreeNode> list = new Queue<TreeNode>();
foreach(TreeNode node in trv.Nodes)
{
    list.Enqueue(node);
}
foreach(TreeNode node in list)
{
    foreach(TreeNode childNode in node.Nodes)
    {
        list.Enqueue(childNode);
    }
}
person Leahn Novash    schedule 13.04.2009

Ладно, вот как далеко я зашел. К сожалению, это очень уродливо, и я до сих пор вручную кодирую, как DEEP в него входить. Также это не мешает цветам находиться рядом друг с другом. Предложения?

foreach (TreeNode treeNode in treeView1.Nodes)
        {
            treeNode.ForeColor = treeNode.Index % 2 == 0 ? Color.DodgerBlue : Color.Goldenrod;

            foreach (TreeNode childNode in treeNode.Nodes)
            {
                childNode.ForeColor = childNode.Index % 2 == 0 ? Color.Goldenrod : Color.DodgerBlue;

                foreach (TreeNode childChildNode in childNode.Nodes)
                {
                    childChildNode.ForeColor = childChildNode.Index % 2 == 0 ? Color.DodgerBlue : Color.Goldenrod;

                    foreach (TreeNode childChildChildNode in childChildNode.Nodes)
                    {
                        childChildChildNode.ForeColor = childChildChildNode.Index % 2 == 0 ? Color.Goldenrod : Color.DodgerBlue;
                    }
                }
            }
        }
person Refracted Paladin    schedule 08.04.2009

Сделайте это рекурсивно для типа Control, используя дочерний элемент управления из корня TreeView, и проверьте, является ли тип Control типом узла, который вы ищете, приведите, измените фоновый цвет, и все готово.

person JP Alioto    schedule 08.04.2009