- Logický strom reprezentuje základní strukturu kontrolů, které jste si vytvořili v XAML či jinak.
- Vizuální strom pak reprezentuje kompletní sadu která se vyyrenderuje na daném zobrazovacím zařízení.
Pokud tedy chcete něco najít, je vhodnější sáhnout po vizuálním stromu a tento prohledávat. Vzhledem k tomu, že (snad) všechny kontroly jsou odděděné od DependencyObject tak používám k tomuto účelu třídu s extension metodami, které injectují potřebnou funckionalitu přímo do třídy DependencyObject a jsou tak kdykoliv k dispozici.
Pozn. Zvykl jsem si umísťovat veškeré své extension metody do stejného namespace jako je cílová třída, do které se injektují. Uznávám, že to není úplně čisté řešení - může dojít ke konfliktům, při přechodu na novější verzi .NET, pokud by Microsoft použil stejně pojmenované metody. Ale jsem líný (asi jako každý programátor) a vyhovuje mi, že mohu používat extensions kdekoliv bez toho abych si musel vzpomenout, jakou namespace musím přidat :-).
namespace System.Windows
{
public static class DependencyObjectExtensions
{
public static T FindFirstVisualChild<T>(this DependencyObject current) where T : DependencyObject
{
if (current == null) return null;
var children = new List<DependencyObject> { current };
var currentIndex = 0;
while (currentIndex < children.Count)
{
current = children[currentIndex];
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(current); i++) {
var child = VisualTreeHelper.GetChild(current, i);
if (child is T) {
return (T) child;
}
children.Add(child);
}
currentIndex++;
}
return null;
}
public static T FindVisualParent<T>(this DependencyObject element) where T : DependencyObject
{
var parent = element;
while (parent != null) {
if (parent is T) {
return (T)parent;
}
parent = VisualTreeHelper.GetParent(parent);
}
return null;
}
}
}
Pokud někde v kódu potřebujete najít rodiče nebo potomka (prvního při hledání do šířky) daného typu, stačí provolat výše uvedené metody. Daly by se zapsat i elegantněji přes rekurzi, ale v době psaní jsem měl zrovna náladu na toto řešení :-).
Žádné komentáře:
Okomentovat