Изменение шаблона данных TreeView во время выполнения

У меня есть TreeView с 3 уровнями в моем приложении WPF.

Уровень 1 и уровень 2 имеют свои собственные HierarchicalDataTemplate, Уровень 3 имеет свой DataTemplate,

Вот код XAML:

<Window.Resources>
    <HierarchicalDataTemplate x:Key="Level1Template" 
                          ItemsSource="{Binding Value}"
                          ItemTemplate="{StaticResource Level2RedTemplate}">
        <Border Background="Green">
            <TextBlock Text="Level1"/>
        </Border>
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate x:Key="Level2RedTemplate"
                          ItemsSource="{Binding Value}"
                          ItemTemplate="{StaticResource Level3Template}">
        <Border Background="Red">
            <TextBlock Text="Level2"/>
        </Border>
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate x:Key="Level2YellowTemplate"
                          ItemsSource="{Binding Value}"
                          ItemTemplate="{StaticResource Level3Template}">
        <Border Background="Yellow">
            <TextBlock Text="Level2"/>
    </HierarchicalDataTemplate>

    <DataTemplate x:Key="Level3Template">
        <Border Background="LightBlue">
            <TextBlock Text="Level3"/>
        </Border>
    </DataTemplate>

</Window.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Button Grid.Row="0"
            Content="Change Template"
            Click="ChangeTemplate" />

    <TreeView Grid.Row="1"
              Name="tv"
              ItemsSource="{Binding Items}"
              ItemTemplate="{StaticResource Level1Template}"/>
</Grid>

Это работает отлично, пока здесь. Проблема начинается, когда я хочу изменить DataTemplate предметов уровня 2, нажав кнопку в моем окне (см. рисунок ниже).

Я пытался назначить новый HierarchicalDataTemplate к моему TreeView из кода позади (в обработчике события кнопки) вот так:

Private Sub ChangeTemplate()

    CType(tv.ItemTemplate, HierarchicalDataTemplate).ItemTemplate = CType(Me.FindResource("Level2YellowTemplate"), HierarchicalDataTemplate)

End Sub

Это невозможно, так как я получаю сообщение об ошибке, что "как только объект-шаблон используется (запечатывается), он не может быть изменен".

Есть ли способ, которым я могу изменить этот шаблон?

1 ответ

Решение

Благодаря полезному комментарию от @Bob, я решил проблему следующим образом:

Я определил свойство в UserControlгде у меня есть TreeView,

Я изменил HierarchicalDataTemplate уровня 1 вот так:

<HierarchicalDataTemplate x:Key="Level1Template" 
                      ItemsSource="{Binding Value}"
                      ItemTemplateSelector="{StaticResource MySelector}">
    <Border Background="Green">
        <TextBlock Text="Level1"/>
    </Border>
</HierarchicalDataTemplate>

Я реализовал MySelector класс и реализовал Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate функция. С использованием containerЯ мог получить доступ к своему UserControl и его свойства.

ItemsSource из моего TreeView изменяется, когда я нажимаю кнопку в моем пользовательском контроле. После каждого изменения TemplateSelector называется, и поэтому шаблон обновляется.

Другие вопросы по тегам