現在這可能比它的價值更麻煩,但儘管如此,它現在對我來說真的很有用。Silverlight&Visual Tree Manipulation
我想知道的是如何在運行時操縱Silverlight可視化樹。做簡單的事情,比如添加和刪除控件很容易,但是當你開始必須以合理的複雜度遍歷樹時,我發現自己渴望用於處理DOM節點替換的JQuery樣式語法(LINQ將會非常酷) ,運動等。
所以我想問的是,有沒有什麼圖書館讓這個工作變得更容易,或者有沒有烤過的東西,我錯過了?
現在這可能比它的價值更麻煩,但儘管如此,它現在對我來說真的很有用。Silverlight&Visual Tree Manipulation
我想知道的是如何在運行時操縱Silverlight可視化樹。做簡單的事情,比如添加和刪除控件很容易,但是當你開始必須以合理的複雜度遍歷樹時,我發現自己渴望用於處理DOM節點替換的JQuery樣式語法(LINQ將會非常酷) ,運動等。
所以我想問的是,有沒有什麼圖書館讓這個工作變得更容易,或者有沒有烤過的東西,我錯過了?
是LINQ的擴展方法是你所追求的,但你必須首先把就地豆蔻基礎設施: -
public static class VisualTreeEnumeration
{
public static IEnumerable<DependencyObject> Descendents(this DependencyObject root, int depth)
{
int count = VisualTreeHelper.GetChildrenCount(root);
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(root, i);
yield return child;
if (depth > 0)
{
foreach (var descendent in Descendents(child, --depth))
yield return descendent;
}
}
}
public static IEnumerable<DependencyObject> Descendents(this DependencyObject root)
{
return Descendents(root, Int32.MaxValue);
}
public static IEnumerable<DependencyObject> Ancestors(this DependencyObject root)
{
DependencyObject current = VisualTreeHelper.GetParent(root);
while (current != null)
{
yield return current;
current = VisualTreeHelper.GetParent(current);
}
}
}
現在你可以使用LINQ查詢到使用LINQ可視化樹。一些例子: -
// Get all text boxes in usercontrol:-
this.Descendents().OfType<TextBox>();
// All UIElement direct children of the layout root grid:-
LayoutRoot.Descendents(0).OfType<UIElement>();
// Find the containing `ListBoxItem` for an element:-
elem.Ancestors().OfType<ListBoxItem>.FirstOrDefault();
// Seek button with name "PinkElephants" even if outside of the current Namescope:-
this.Descendents()
.OfType<Button>()
.FirstOrDefault(b => b.Name == "PinkElephants");
您可能會對此LINQ to Visual Tree實施感興趣。
什麼版本的silverlight是這樣的? 「12月13日13:13」是哪一年?
在當前版本SL4它似乎並沒有在那裏..
我用這個代碼從可視樹得到控制
public static FrameworkElement GetComponent(object child, Type t, Type bailOn)
{
if (child == null) return null;
DependencyObject control = (DependencyObject)child; // VisualTreeHelper.GetParent((DependencyObject)x);
while (control != null)
{
if (!control.Equals(child))
{
if (control.GetType() == t)
{
break;
}
}
if (control is FrameworkElement)
{
control = (control as FrameworkElement).Parent;
}
else if ((control is DataGridBoundColumn)) // data grid fucken columns
{
control = GetDataGridBoundColumnDataGrid(control);
}
if (control != null && bailOn != null && bailOn.GetType() == control.GetType())
{
return null;
}
}
// try VTH as we did not find it, as that works some times and the above does not
if (control == null)
{
control = (DependencyObject)child; // start again
while (control != null)
{
if (!control.Equals(child))
{
if (control.GetType() == t)
{
break;
}
}
if (control is FrameworkElement)
{
control = VisualTreeHelper.GetParent((control as FrameworkElement));
}
else if (control is DataGridBoundColumn)
{
control = GetDataGridBoundColumnDataGrid(control);
}
if (control != null && bailOn != null && bailOn.GetType() == control.GetType())
{
return null;
}
}
}
return control as FrameworkElement;
}
public static List<FrameworkElement> GetComponentsByType(FrameworkElement parent, Type type)
{
List<FrameworkElement> controls = new List<FrameworkElement>();
GetComponentsByTypeWorker(parent, type, controls);
return controls;
}
private static void GetComponentsByTypeWorker(FrameworkElement parent, Type type, List<FrameworkElement> controls)
{
if (parent.GetType() == type)
{
controls.Add(parent as FrameworkElement);
}
int cnt = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < cnt; i++)
{
FrameworkElement child = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
if (child.GetType() == type)
{
controls.Add(child as FrameworkElement);
}
int cnt2 = VisualTreeHelper.GetChildrenCount(child);
for (int j = 0; j < cnt2; j++)
{
FrameworkElement child2 = VisualTreeHelper.GetChild(child, j) as FrameworkElement;
GetComponentsByTypeWorker(child2 as FrameworkElement, type, controls);
}
}
}
真棒...感謝一大堆。 – Stimul8d 2010-12-13 13:51:11