次のXAMLのようなリストボックスがWPFにあります。チェックボックスとラベルが入ったListBoxItemがいっぱいです。一番上の私の項目の1つは、「すべて選択」オプションです。[すべて選択]オプションをクリックすると、すべてのリストボックスアイテムを反復処理するハンドラーがあり、他のすべてのリストボックスの子のすべてのチェックボックスをオンにすることになっています。問題は、表示されている子のみを実行しており、表示されていないlistboxitemsにヒットすると、特定のタイプのオブジェクト(CheckBoxなど)を検索するときにVisualTreeHelperがnullを返しているように見えることです。VisualTreeHelperはここで問題があるようです。私はそれを間違って使用していますか?助けていただければ幸いです。もう1つの詳細-すべてのリストボックスアイテムを少なくとも1回スクロールして表示すると、正常に機能します。
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#-2つの関数。1つはVisualTreeHelperを使用してオブジェクトツリーをウォークするヘルパーメソッドです(これはいくつかのWebサイトで見つかりました)。2番目の関数は、「すべて選択」リストボックスアイテムのクリックハンドラーです。すべての子を繰り返し処理し、すべてのチェックボックスをオンにしようとします。
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);
}
}
}
}
}