Reputation: 32223
How can I access the ItemsPanel of a ListBox at runtime in silverlight?
Upvotes: 1
Views: 660
Reputation: 35
Building on terphi's solution, i changed it to return a list of the elements you are looking for as normally when your searching for a type, the listbox will have multiple items and multiple instances of what you are looking for. Additionally, I had issues with it finding things in the loaded event but used a dispatcher instead and it finds the items every time in testing.
private List<TextBlock> TextBlockList;
in the constructor, after associating the datasource with listbox:
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;
}
Upvotes: 0
Reputation: 781
Given the following element declaration in XAML
<ListBox x:Name="LB" Loaded="LB_Loaded" />
There are two ways to achieve this, the easiest requires the Silverlight toolkit:
using System.Windows.Controls.Primitives;
private void LB_Loaded()
{
var itemsPanel = LB.GetVisualChildren().OfType<Panel>().FirstOrDefault();
}
Or you can use the VisualTreeHelper and write the following recursive method:
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;
}
And get the result in a similar manner:
void ItemsPanelSample_Loaded(object sender, RoutedEventArgs e)
{
var itemsPanel = GetFirstChildOfType<Panel>(LB);
}
Upvotes: 2