Как мне пройти через все слои узлов Treeview? - PullRequest
4 голосов
/ 08 апреля 2009

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

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

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

Спасибо

EDIT

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

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

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

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

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

Ответы [ 5 ]

3 голосов
/ 09 апреля 2009

Рекурсия

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

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);
       }
    }
2 голосов
/ 14 апреля 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);
    }
}
2 голосов
/ 08 апреля 2009

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

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

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

Me.TreeView1.Nodes(0).BackColor = Color.AliceBlue  
0 голосов
/ 09 апреля 2009

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

0 голосов
/ 09 апреля 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;
                    }
                }
            }
        }
...