Динамический выбор шаблона DataTemplateSelector

Бывает ситуация, когда заранее не знаеш, какой шаблон необходимо подключить. Для этого WPF предусматривает DataTemplateSelector. Давайте на примере посмротрим, как всё это работает.
Создадим простое WPF приложение. Разместим на форме ComboBox и ContentPresenter:

<Window x:Class="TemplateSelectorContentPresenter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="240" Width="344">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <ComboBox Grid.Row="0" SelectionChanged="OnChange" Margin="5">
            <ComboBoxItem>Button</ComboBoxItem>
            <ComboBoxItem>TextBlock</ComboBoxItem>
            <ComboBoxItem>RadioButtons</ComboBoxItem>
        </ComboBox>
        <ContentPresenter x:Name="presenter" Grid.Row="1" Margin="5" />
    </Grid>
</Window>

В нашем случае в выпадающем списке есть три варианта:

  • Button
  • TextBlock
  • RadioButton
    Определим для каждого варианта свой шаблон:

    <Window.Resources>
        <DataTemplate x:Key="ButtonTemplate">
            <Button Content="Click Me" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Center" />
        </DataTemplate>
    
        <DataTemplate x:Key="TextBlockTemplate">
            <TextBlock Text="TextBlock" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Center" />
        </DataTemplate>
    
        <DataTemplate x:Key="RadioButtonsTemplate" >
            <Grid Margin="5" VerticalAlignment="Center" HorizontalAlignment="Center" >
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <RadioButton Content="Variant 1" Grid.Row="0" />
                <RadioButton Content="Variant 2" Grid.Row="1" />
                <RadioButton Content="Variant 3" Grid.Row="2" />
            </Grid>
        </DataTemplate>
    </Window.Resources>
    

    Для ComboBox подпишемся на событие SelectionChanged. В обработчике мы будем присваивать свойтсву Content ContentPresenter-а выбраный индекс:

    private void OnChange(object sender, SelectionChangedEventArgs e)
    {
        ComboBox cb = sender as ComboBox;
        if (cb != null && presenter != null)
            presenter.Content = cb.SelectedIndex;
    }
    

    Теперь определим наш DataTemplateSelector:

    public class TemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            //получаем вызывающий контейнер
            FrameworkElement element = container as FrameworkElement;
    
            if (element != null && item != null && item is int)
            {
                int currentItem = 0;
    
                int.TryParse(item.ToString(), out currentItem);
                //в зависимости от того, какой вариант выбран, возвращаем конкретный шаблон
                if (currentItem == 0)
                    return element.FindResource("ButtonTemplate") as DataTemplate;
                if (currentItem == 1)
                    return element.FindResource("TextBlockTemplate") as DataTemplate;
                if (currentItem == 2)
                    return element.FindResource("RadioButtonsTemplate") as DataTemplate;
            }
            return null;
        }
    }
    

    Подключаем простарнство имён:

    xmlns:local="clr-namespace:TemplateSelectorContentPresenter"
    

    Определяем ресурс:

    <local:TemplateSelector x:Key="templateSelector" />
    

    Подключаем наш TemaplteSelector к ContentPresenter

    Определяем ресурс:

    <ContentPresenter x:Name="presenter" Grid.Row="1" Margin="5"
                              ContentTemplateSelector="{StaticResource templateSelector}" />
    

    Запускаем приложение!

    Вот и всё…

      TemplateSelectorContentPresenter.rar (89,1 KiB, 1 867 закачек)

    Поделиться в соц. сетях

    Опубликовать в Facebook
    Опубликовать в Google Plus
    Опубликовать в LiveJournal
    Опубликовать в Google Buzz
    Опубликовать в Одноклассники
    Опубликовать в Яндекс
    Опубликовать в Мой Мир

    Похожие статьи

  • Комментарии (10) на “Динамический выбор шаблона DataTemplateSelector”

    Добавить комментарий для Bestlis