基于可见性定义交替TreeView行的背景颜色

时间:2010-08-06 15:41:03

标签: wpf treeview

WPF中有没有办法定义交替显示行的背景?

我已尝试设置AlternationCount属性,但会为每个子节点重新启动,这会产生奇怪的外观。

理想情况下,我想知道给定节点的可视索引是什么。仅计算扩展节点。

2 个答案:

答案 0 :(得分:4)

没有简单的方法可以做到这一点,因为WPF为树节点创建了嵌套容器。正如雷切尔所提到的,循环遍历这些项目似乎是要走的路。但是我不想从内置的ItemsControl.AlternationIndex附加属性中离开太多,因为这是人们所期望的。因为它是只读的,所以我必须通过反射访问它,但之后事情就会落到实处。

首先,确保处理TreeViewItem的Loaded,Expanded和Collapsed事件。在事件处理程序中找到拥有的TreeView并执行所有可见节点的递归交替计数集。我创建了一个扩展方法来处理它:

  public static class AlternationExtensions
  {

    private static readonly MethodInfo SetAlternationIndexMethod;

    static AlternationExtensions()
    {
        SetAlternationIndexMethod = typeof(ItemsControl).GetMethod(
        "SetAlternationIndex", BindingFlags.Static | BindingFlags.NonPublic);
    }

    public static int SetAlternationIndexRecursively(this ItemsControl control, int firstAlternationIndex)
    {
        var alternationCount = control.AlternationCount;
        if (alternationCount == 0)
        {
            return 0;
        }

        foreach (var item in control.Items)
        {
            var container = control.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
            if (container != null)
            {
                var nextAlternation = firstAlternationIndex++ % alternationCount;
                SetAlternationIndexMethod.Invoke(null, new object[] { container, nextAlternation });
                if (container.IsExpanded)
                {
                    firstAlternationIndex = SetAlternationIndexRecursively(container, firstAlternationIndex);
                }
            }
        }

        return firstAlternationIndex;
    }
}

如您所见,它贯穿每个节点并设置自定义交替索引。它检查节点是否已展开,如果是,则继续对子节点进行计数。

上面我提到你必须处理TreeViewItem的Loaded事件。如果只处理展开和折叠事件,则不会获得首次打开节点时创建的新容器。因此,在创建子节点并将其添加到可视树时,您必须执行新的传递。

答案 1 :(得分:0)

我用javascript做的事情是为一个循环表行的表创建一个OnLoaded事件,如果行是可见的,它将背景颜色设置为nextColor变量,并将nextColor变量更改为相反的颜色。这可能在这里有效。