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

标签 wpf mvvm datatemplate datatrigger

我目前有一个类别列表。对于每个类别,将使用扩展器和数据网格创建一个模板,该模板将显示与该类别关联的项目列表。
我的问题是,如果没有某个类别的项目,则我不想为该类别创建模板。
目前,我可以隐藏该模板,但是在制作模板的地方留下了空白。

<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中的每个项目提供不同的数据模板,这取决于运行时运行的某些逻辑。

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

我个人认为这种方法比触发器更干净,尽管从逻辑上讲它们非常相似。

希望这会有所帮助。

关于wpf - 如何停止在特定条件下创建模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8819369/

相关文章:

wpf - 动态更改数据模板

c# - 制作 NxN tic tac toe GUI wpf c#

wpf - 有没有比 White 更好的 WPF 自动化测试工具?

ios - ReactiveCocoa 4,根据 UI 事件和验证正确发送我的 HTTP 请求

c# - 如何在 C# 代码中构建 DataTemplate?

c# - ListView 内的 TextBox 绑定(bind)到对象,双向绑定(bind)不起作用

wpf - 组合框 TextWrap 绑定(bind)

c# - 以编程方式更改 StackPanel 在 Canvas 上的位置

wpf - 使用 MVVM Light 从组合框中的按钮触发命令

wpf - 有效地重用 View