gpt4 book ai didi

c# - 如何获得 ListBox 的子控件?

转载 作者:太空宇宙 更新时间:2023-11-03 23:43:31 25 4
gpt4 key购买 nike

我在 xaml 中有一个 ListBox,它在顶级 ListBox 的项目模板中有一个子 ListBox。因为子列表框是多选的,而且出于某种原因我无法将子列表框的 SelectedItems 绑定(bind)到 View 模型属性,所以我试图在 View 代码隐藏中做很多这样的事情。

我一切正常,除了一个障碍:我想默认选择每个子列表框中的所有项目。由于 SelectedItems 不是数据绑定(bind)的,因此每当在顶级 ListBox 上触发 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>

转换器确保只有选定的顶级项目有一个可见的子列表框,并且这是有效的。

我需要实现以下方法:

private void StuffListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox stuffListBox = (ListBox)sender;

foreach (Stuff stuff in e.AddedItems)
{
...
subStuffListBox.SelectAll();
}
}

我尝试执行 stuffListBox.ItemContainerGenerator.ContainerFromItem(stuff),但总是返回 null。甚至 stuffListBox.ItemContainerGenerator.ContainerFromIndex(0) 也总是返回 null。

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

据我了解,我的问题是在我收到选择更改事件时容器尚未生成。我已经看到涉及监听项目容器生成器的状态更改事件的解决方法,但我在 Silverlight 中工作并且无权访问该事件。由于疏忽了将 ListBox 上的 SelectedItems 设置为只读,我在 Silverlight 中做的事情是不可能的吗?

最佳答案

就像你说的那样,这可能最好在 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 方法根据 MSDN

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;
}

关于c# - 如何获得 ListBox 的子控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28287807/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com