C# 如何获取列表框的子控件?

C# 如何获取列表框的子控件?,c#,xaml,silverlight,listbox,C#,Xaml,Silverlight,Listbox,我在xaml中有一个列表框,它在顶级列表框的项目模板中有一个子列表框。由于子列表框是多选的,并且由于某种原因,我无法将子列表框的SelectedItems绑定到viewmodel属性,因此我尝试在后面的视图代码中执行很多操作 除了一个障碍外,我的一切都正常工作:默认情况下,我想选择每个子列表框中的所有项目。由于SelectedItems没有数据绑定,所以每当在顶级列表框上触发SelectionChanged事件时,我都会尝试在代码中手动执行此操作。问题是我不知道如何从顶级列表框到顶级选定项的子列

我在xaml中有一个列表框,它在顶级列表框的项目模板中有一个子列表框。由于子列表框是多选的,并且由于某种原因,我无法将子列表框的SelectedItems绑定到viewmodel属性,因此我尝试在后面的视图代码中执行很多操作

除了一个障碍外,我的一切都正常工作:默认情况下,我想选择每个子列表框中的所有项目。由于SelectedItems没有数据绑定,所以每当在顶级列表框上触发SelectionChanged事件时,我都会尝试在代码中手动执行此操作。问题是我不知道如何从顶级列表框到顶级选定项的子列表框。我想我需要使用可视化树,但我甚至不知道如何获取与所选项对应的依赖项对象

代码如下:

<ListBox ItemsSource="{Binding Path=Stuff}" SelectionChanged="StuffListBox_SelectionChanged" SelectedItem="{Binding Path=SelectedStuff, Mode=TwoWay}" telerik:RadDockPanel.Dock="Bottom">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <telerik:RadDockPanel>
            <TextBlock Text="{Binding Path=Name}" telerik:RadDockPanel.Dock="Top" />
                <ListBox ItemsSource="{Binding Path=SubStuff}" SelectionMode="Multiple" SelectionChanged="SubStuffListBox_SelectionChanged" Visibility="{Binding Converter={StaticResource StuffToSubStuffVisibilityConverter}}" telerik:RadDockPanel.Dock="Bottom">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=Name}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </telerik:RadDockPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
我尝试过执行stuffListBox.ItemContainerGenerator.ContainerFromItemstuff,但它总是返回null。即使是stuffListBox.ItemContainerGenerator.ContainerFromIndex0也始终返回null

我还从改变选择的方法中得到了奇怪的行为。”e、 AddedItems将包含项,但stuffListBox.SelectedItem始终为空。我错过什么了吗


从我所读到的内容来看,我的问题来自这样一个事实,即在我获取选择更改事件时,容器还没有生成。我见过一些解决方法,包括侦听条目容器生成器的状态更改事件,但我在Silverlight中工作,无法访问该事件。我在Silverlight中所做的是不可能的,因为没有将列表框上的SelectedItems设置为只读吗?

正如您所说,这可能最好在ViewModel中完成,但您可以使用VisualTreeHelper在代码隐藏中选择所有子列表项

private void StuffListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   var stuffListBox = (ListBox)sender;
        ListBoxItem item = (ListBoxItem)stuffListBox.ContainerFromItem(stuffListBox.SelectedItem);
        ListBox sublist = FindVisualChild<ListBox>(item);
        sublist.SelectAll();
}
根据的FindVisualChild方法


你调试过这个代码吗?由于某种原因,无法将子列表框的SelectedItems绑定到viewmodel属性-可能是因为子列表框的数据上下文是父列表框,而不是最有可能将视图模型作为数据上下文的视图。使用RelativeSource访问视图模型。@PaulAbbott绑定SelectedItems的问题是它是只读属性,所以我不能将它绑定到任何东西。ContainerFromElement呢?@user2585308该方法在ItemContainerGenerator或ListBox上不存在。ListBox没有ContainerFromItem方法。您的ListBox有ItemContainerGenerator.ContainerFromItem吗?如果不是你的应用程序WP8.1或其他什么,但正如我在问题中提到的,它在传递源项时总是返回null。我刚刚在sliverlight应用程序中测试了上述代码,它可以工作。选定子列表框的选定项。你为什么使用e.AddedItems?使用stuffListBox.ItemContainerGenerator.ContainerFromItemstuffListBox.SelectedItem我也尝试使用stuffListBox.SelectedItem,但SelectedItem始终为空,即使由于刚刚选择了某些内容而触发了SelectionChange事件。
private void StuffListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   var stuffListBox = (ListBox)sender;
        ListBoxItem item = (ListBoxItem)stuffListBox.ContainerFromItem(stuffListBox.SelectedItem);
        ListBox sublist = FindVisualChild<ListBox>(item);
        sublist.SelectAll();
}
private childItem FindVisualChild<childItem>(DependencyObject obj)
    where childItem : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    {
       DependencyObject child = VisualTreeHelper.GetChild(obj, i);
       if (child != null && child is childItem)
          return (childItem)child;
       else
       {
          childItem childOfChild = FindVisualChild<childItem>(child);
          if (childOfChild != null)
            return childOfChild;
       }
 }
 return null;
}