如何在Silverlight中运行时访问ListBox的ItemsPanel?
答案 0 :(得分:2)
在XAML中给出以下元素声明
<ListBox x:Name="LB" Loaded="LB_Loaded" />
有两种方法可以实现这一点,最简单的方法是使用Silverlight工具包:
using System.Windows.Controls.Primitives;
private void LB_Loaded()
{
var itemsPanel = LB.GetVisualChildren().OfType<Panel>().FirstOrDefault();
}
或者您可以使用VisualTreeHelper并编写以下递归方法:
T GetFirstChildOfType<T>(DependencyObject visual) where T:DependencyObject
{
var itemCount = VisualTreeHelper.GetChildrenCount(visual);
if (itemCount < 1)
{
return null;
}
for (int i = 0; i < itemCount; i++)
{
var dp = VisualTreeHelper.GetChild(visual, i);
if (dp is T)
{
return (T)dp;
}
}
for (int i = 0; i < itemCount; i++)
{
var dp = GetFirstChildOfType<T>(VisualTreeHelper.GetChild(visual, i));
if (dp != null) return dp;
}
return null;
}
以类似的方式获得结果:
void ItemsPanelSample_Loaded(object sender, RoutedEventArgs e)
{
var itemsPanel = GetFirstChildOfType<Panel>(LB);
}
答案 1 :(得分:0)
在terphi的解决方案的基础上,我改变它以返回您正在寻找的元素列表,正常情况下,当您搜索类型时,列表框将包含多个项目以及您正在寻找的多个实例。另外,我遇到了问题,它在加载的事件中查找事物,但是使用了调度程序,每次测试时都会找到项目。
private List<TextBlock> TextBlockList;
在将数据源与列表框关联后,在构造函数中:
Dispatcher.BeginInvoke(delegate { TextBlockList = GetFirstChildOfType<TextBlock>(listBox1); });
List<T> GetFirstChildOfType<T>(DependencyObject visual) where T : DependencyObject
{
DependencyObject ControlCandidate;
List<T> TempElements;
List<T> TargetElementList = new List<T>();
var itemCount = VisualTreeHelper.GetChildrenCount(visual);
if (itemCount > 0)
{
for (int i = 0; i < itemCount; i++)
{
ControlCandidate = VisualTreeHelper.GetChild(visual, i);
if (ControlCandidate is T)
TargetElementList.Add((T)ControlCandidate);
}
for (int i = 0; i < itemCount; i++)
{
TempElements = GetFirstChildOfType<T>(VisualTreeHelper.GetChild(visual, i));
if (TempElements.Count > 0)
TargetElementList.AddRange(TempElements);
}
}
return TargetElementList;
}