【问题标题】:Is it possible to have a DataTemplate around another DataTemplate?是否可以在另一个 DataTemplate 周围有一个 DataTemplate?
【发布时间】:2018-11-14 21:24:00
【问题描述】:

大家好,欢迎来到另一个嵌套 DataTemplate 问题!

在这个中,我想要一个这样的 DataTemplate,写在 ResourceDictionary 上:

<DataTemplate x:Key="Vector3Template">
    <StackPanel Orientation="Horizontal">
        <StackPanel Orientation="Horizontal">
            <xctk:DoubleUpDown Tag="X" Style="{StaticResource DoubleUpDownStyle}" Value="{Binding X}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <xctk:DoubleUpDown Tag="Y" Style="{StaticResource DoubleUpDownStyle}" Value="{Binding Y}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <xctk:DoubleUpDown Tag="Z" Style="{StaticResource DoubleUpDownStyle}" Value="{Binding Z}"/>
        </StackPanel>
    </StackPanel>
</DataTemplate>

被带有边框的 DataTemplate 包围,如下所示,也写在 ResourceDictionary 上(将来它会有更多元素):

<DataTemplate x:Key="ComponentTemplate">
    <Border Margin="5" BorderThickness="2" BorderBrush="Gray"/>
</DataTemplate>

你问我为什么要这个?好吧,我正在尝试显示名为 _components 的 IComponent 的 ObservableCollection,我希望所有实例共享相同的边框,但其核心特定于从 IComponent 继承的每个类类型。

为了显示具有不同类型的列表,我在 UserControl 上使用以下代码:

<Grid x:Name="LayoutRoot" Background="White">        
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
    <StackPanel>
        <ListView x:Name="_componentsList" 
                 ItemsSource="{Binding Components}" 
                 HorizontalContentAlignment="Stretch">
            <ListView.Resources>
                <DataTemplate DataType="{x:Type models:Transform}">
                    <ContentControl Content="{StaticResource ComponentTemplate}" ContentTemplate="{StaticResource TransformTemplate}"/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type models:Vector3}">
                    <ContentPresenter ContentTemplate="{StaticResource Vector3Template}"/>
                </DataTemplate>
            </ListView.Resources>
        </ListView>
    </StackPanel>
</ScrollViewer>

尝试使用 Prism 6.3 构建这个系统并且几乎没有代码隐藏,我拥有的每个 c# 代码都只是用于模型,所以到目前为止还没有真正的逻辑。

这可能吗?怎么会这样?几天前我开始玩 WPF,还有很多东西要学。

【问题讨论】:

  • “共享相同的边框”由 ItemsControl 的 ItemContainerStyle 中的 Template 属性的 Style Setter 设置的 ControlTemplate。在 ControlTemplate 的边框中放置一个 ContenPresenter。除此之外,ScrollViewer 中 StackPanel 中的 ListView 看起来很奇怪。 ListView 已经支持滚动。
  • 以某种方式设置 VerticalContentAlignment="Top" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.Horizo​​ntalScrollBarVisibility="Disabled" 不起作用..我要么禁用verticalScroll 要么根本没有verticalScroll 但你绝对对,设置 ItemContainerStyle 确实有效
  • 这个问题问的是一个 XY 问题...你认为 DataTemplate 是做你想做的事情的方式,但你想要的是一个通用的模板化容器(它纯粹是视觉的,不依赖于数据) 具有专门的数据模板化内容区域(显示数据 = DataTemplate)。简而言之:嵌套的DataTemplate 不是您想要的。你应该围绕你的实际需求写你的问题,只提到你对可能解决方案的想法,而不是写关于可能解决方案的问题,只提到要解决的实际问题。

标签: wpf prism datatemplate resourcedictionary contentcontrol


【解决方案1】:

我相信您正在寻找的是简单地使用 DataTemplateSelector,其中使用的 DataTemplate 由数据确定。你可以找到完整的教程here。设置好 DataTemplateSelector 后,您只需将其作为 DataTemplate 传递给您的控件。

public class PropertyDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate DefaultnDataTemplate { get; set; }
    public DataTemplate BooleanDataTemplate { get; set; }
    public DataTemplate EnumDataTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, 
            DependencyObject container)
    {
        DependencyPropertyInfo dpi = item as DependencyPropertyInfo;
        if (dpi.PropertyType == typeof(bool))
        {
            return BooleanDataTemplate;
        }
        if (dpi.PropertyType.IsEnum)
        {
            return EnumDataTemplate;
        }

        return DefaultnDataTemplate;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 2014-11-26
    • 1970-01-01
    • 2013-06-28
    • 2011-03-05
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多