There was no easy way to do this, since WPF creates nested containers for tree nodes. So, as Rachel mentioned, passing through objects seemed to be a way. But I did not want to go too far from the built-in ItemsControl.AlternationIndex property, as this is the one that people expected. Since this is read-only, I had to access it through reflection, but after that everything fell into place.
First of all, make sure that you handle the Loaded, Expanded, and Collapsed events of your TreeViewItem. In the event handler, find your own TreeView and make a recursive rotation counter for all visible nodes. I created an extension method to handle it:
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;
}
}
, node . , node, .
, Loaded TreeViewItem. , , node. , node .