Wpf 如何在特定条件下停止创建模板

Wpf 如何在特定条件下停止创建模板,wpf,mvvm,datatemplate,datatrigger,Wpf,Mvvm,Datatemplate,Datatrigger,我目前有一个类别列表。对于每个类别,将使用扩展器和datagrid创建一个模板,该模板将显示与该类别关联的项目列表。 我的问题是,如果某个类别没有项目,我不希望为该类别创建模板。 目前,我可以得到模板隐藏,但它留下了一个缺口,模板已经作出 <StackPanel Name="CatagoryPanel" Grid.Row="2" Grid.ColumnSpan="6"> <ItemsControl ItemsSource="{Binding Path=C

我目前有一个类别列表。对于每个类别,将使用扩展器和datagrid创建一个模板,该模板将显示与该类别关联的项目列表。 我的问题是,如果某个类别没有项目,我不希望为该类别创建模板。 目前,我可以得到模板隐藏,但它留下了一个缺口,模板已经作出

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

最近我发现ItemsControl的ItemTemplateSelector属性,它允许您为ItemsControl中的每个项目提供不同的数据模板,这取决于运行时运行的某些逻辑

与塞特相似,但更优雅

首先,定义从DataTemplateSelector派生的类。正确的位置是在代码隐藏*.cs文件中(因为这是视图的一部分)

接下来,在堆栈面板中,将两个数据模板以及选择器定义为资源:

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

就我个人而言,我发现这种方法比触发器更干净,尽管它们在逻辑上非常相似


希望这有所帮助。

最近我发现ItemsControl的ItemTemplateSelector属性,它允许您为ItemsControl中的每个项提供不同的数据模板,这取决于运行时运行的某些逻辑

与塞特相似,但更优雅

首先,定义从DataTemplateSelector派生的类。正确的位置是在代码隐藏*.cs文件中(因为这是视图的一部分)

接下来,在堆栈面板中,将两个数据模板以及选择器定义为资源:

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

就我个人而言,我发现这种方法比触发器更干净,尽管它们在逻辑上非常相似


希望这有帮助。

必须尝试将可见性设置为崩溃???啊,我没想到!谢谢旁注:我想你忘了在扩展器和DataGrid周围有一个面板(例如StackPanel,见下面我的答案)。我不认为DataTemplate可以有两个可视元素。是的,你是正确的,我在网格中有它们。必须尝试将可视性设置为折叠???啊,我没想到!谢谢旁注:我想你忘了在扩展器和DataGrid周围有一个面板(例如StackPanel,见下面我的答案)。我不认为DataTemplate可以有两个可视元素。是的,你是对的,我在网格中有它们。