我在WPF中有一个列表框,就像下面的XAML一样。它充满了ListBoxItems,里面有一个复选框和一个标签。我在顶部的一个项目是“全选”选项。当我单击全选选项时,我有一个处理程序,它遍历所有列表框项目,它应该检查所有其他列表框子项上的所有复选框。问题是它只是在做可见的孩子,当它遇到不可见的listboxitems时,VisualTreeHelper似乎在寻找特定类型的对象(如CheckBox)时返回null。似乎VisualTreeHelper在这里似乎有问题。我用错了吗?任何帮助赞赏。另一个细节 - 如果我滚动并查看所有listboxitems至少一次,它可以正常工作。
MJ
XAML - 一个包含大量孩子的简单列表框(为简洁起见,只展示了第一个孩子)
<ListBox Grid.Row="0" Margin="0,0,0,0" Name="CharacterListBox">
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" Click="AllCharactersClicked"></CheckBox>
<Label Padding="5">All Characters</Label>
</StackPanel>
</ListBoxItem>
C# - 两个函数,第一个是使用VisualTreeHelper遍历对象树的辅助方法(我在某些网站上发现了这个)。第二个功能是“全选”listboxitem的点击处理程序。它遍历所有子项并尝试检查所有复选框。
private T FindControlByType<T>(DependencyObject container, string name) where T : DependencyObject
{
T foundControl = null;
//for each child object in the container
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(container); i++)
{
//is the object of the type we are looking for?
if (VisualTreeHelper.GetChild(container, i) is T && (VisualTreeHelper.GetChild(container, i).GetValue(FrameworkElement.NameProperty).Equals(name) || name == null))
{
foundControl = (T)VisualTreeHelper.GetChild(container, i);
break;
}
//if not, does it have children?
else if (VisualTreeHelper.GetChildrenCount(VisualTreeHelper.GetChild(container, i)) > 0)
{
//recursively look at its children
foundControl = FindControlByType<T>(VisualTreeHelper.GetChild(container, i), name);
if (foundControl != null)
break;
}
}
return foundControl;
}
private void AllCharactersClicked(object sender, RoutedEventArgs e)
{
MainWindow.Instance.BadChars.Clear();
int count = 0;
foreach (ListBoxItem item in CharacterListBox.Items)
{
CheckBox cb = FindControlByType<CheckBox>(item, null);
Label l = FindControlByType<Label>(item, null);
if (cb != null && l != null)
{
count++;
cb.IsChecked = true;
if (cb.IsChecked == true)
{
string sc = (string)l.Content;
if (sc.Length == 1)
{
char c = Char.Parse(sc);
MainWindow.Instance.BadChars.Add(c);
}
}
}
}
}
答案 0 :(得分:3)
那些遍布整个地方的视觉树木行走方法都是瘟疫。你应该几乎不需要任何这些。
只需将ItemsSource
绑定到包含CheckBoxes
属性的对象列表,创建data template(ItemTemplate
)和bind该属性即可CheckBox
。在代码中,只需遍历绑定到ItemsSource
的集合并设置属性。