首先,您不需要使用 LINQ(或任何 C# 代码!)在下一个 ListBox 上设置 ItemSource。您可以为此使用 WPF 数据绑定:
<ListBox x:Name="listbox1" ItemsSource="{Binding Path=YourDataCollection}"/>
<ListBox x:Name="listbox2" ItemsSource="{Binding ElementName=listbox1, Path=SelectedItem.SubNodes}" />
<ListBox x:Name="listbox3" ItemsSource="{Binding ElementName=listbox2, Path=SelectedItem.SubNodes}" />
基本上,您将下一个列表框绑定到前一个列表框的 SelectedItem 的子节点(您可能应该确保列表框一次只能选择一个)
现在要隐藏没有任何项目的列表框,您可以使用 IValueConverter 将对象转换为可见性状态。为此,请创建一个类:
public class ObjectToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null)
return Visibility.Visible;
else
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
并为您的列表框添加更多数据绑定:
<Window.Resources>
<local:ObjectToVisibilityConverter x:Key="objectToVisible" />
</Window.Resources>
<Grid>
<ListBox x:Name="listbox1" ItemsSource="{Binding ElementName=mw1, Path=dataCollection}"/>
<ListBox x:Name="listbox2" ItemsSource="{Binding ElementName=listbox1, Path=SelectedItem.SubNodes}"
Visibility="{Binding ElementName=listbox2, Path=ItemsSource, Converter={StaticResource objectToVisible}}" />
<ListBox x:Name="listbox3" ItemsSource="{Binding ElementName=listbox2, Path=SelectedItem.SubNodes}"
Visibility="{Binding ElementName=listbox3, Path=ItemsSource, Converter={StaticResource objectToVisible}}" />
</Grid>
确保将你的命名空间添加到窗口中,这样实际上可以找到 valueconverter,在我的例子中,我添加了这个:
xmlns:local="clr-namespace:WpfApplication1"
现在这个解决方案只适用于固定数量的列表框,但它不依赖于任何 C# 代码,除了 valueconverter。你真的不知道你可能需要多少个子级别吗?例如,您可以使用此技术将数十个列表框添加到滚动视图。
为了实际上,在UserControl中使这种动态可能会变得非常痛苦,因为在选择不同的根节点时,将在添加列表框中涉及的大量代码涉及添加列表框,请在选中不同的根节点时设置。
另一种可能性可能是为 TreeView 创建 HierarchicalDataTemplate 以自定义 treeview 的外观。这具有保留树视图的优点,因为它是分层数据最有用的控件,但是使用 WPF 及其模板应该完全可以更改它的外观。不过,您可能需要更改树视图的 controltemplate(我建议使用 Blend 来编辑任何类型的 WPF 模板)