Возможно ли иметь DataTemplate вокруг другого DataTemplate? - PullRequest
0 голосов
/ 15 ноября 2018

Привет всем и добро пожаловать на еще один вложенный вопрос 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>

Почему я хочу этого, спросите вы? Ну, я пытаюсь отобразить ObservableCollection IComponent с именем _components, и я хочу, чтобы все экземпляры имели одни и те же границы, но его ядро ​​было специфичным для каждого типа класса, который наследуется от 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 несколько дней назад, и мне еще есть чему поучиться.

1 Ответ

0 голосов
/ 22 ноября 2018

Я считаю, что вам нужно просто использовать DataTemplateSelector, в котором используемый DataTemplate определяется данными. Вы можете найти полный учебник здесь . После настройки 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;
    }
}
...