我目前有一个类别列表。对于每个类别,使用扩展器和数据网格创建模板,该模板将显示与该类别关联的项目列表。 我的问题是,如果没有类别的项目,我不希望为该类别创建模板。 目前我可以隐藏模板,但是它留下了模板已经制作的空白。
<StackPanel Name="CatagoryPanel" Grid.Row="2" Grid.ColumnSpan="6">
<ItemsControl ItemsSource="{Binding Path=CategoryList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Items.Count, UpdateSourceTrigger=PropertyChanged}" Value="0">
<Setter Property="Visibility" Value="Hidden"/>
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</DataTemplate.Triggers>
<Expander />
<DataGrid />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
答案 0 :(得分:1)
最近我发现了ItemsControl的ItemTemplateSelector属性,它允许你为ItemsControl中的每个项目提供不同的数据模板,这取决于运行时运行的一些逻辑。
与Setter类似,但更优雅。
首先,定义一个从DataTemplateSelector派生的类。正确的地方是在* .cs文件后面的代码中(因为这是View的一部分)。
public class CategoryTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
Category category = item as MusicViewModel.Category;
FrameworkElement element = container as FrameworkElement;
string key = (category.Count) > 0 ? "Category" : "EmptyCategory";
DataTemplate dt = element.FindResource(key) as DataTemplate;
return dt;
}
}
接下来,在堆栈面板中,将两个数据模板定义为资源,以及选择器:
<StackPanel Name="CatagoryPanel" Grid.Row="2" Grid.ColumnSpan="6">
<StackPanel.Resources>
<DataTemplate x:Key="EmptyCategory">
<StackPanel><Expander /><DataGrid /></StackPanel>
</DataTemplate>
<DataTemplate x:Key="Category">
<Expander />
</DataTemplate>
<gms:CategoryTemplateSelector x:Key="selector" />
</StackPanel.Resources>
<!-- now, define the actual ItemsControl: -->
<ItemsControl ItemsSource="{Binding }" ItemTemplateSelector="{StaticResource selector}" />
</StackPanel>
就个人而言,我发现这种方法比触发器更清晰,尽管逻辑上它们非常相似。
希望这会有所帮助。