Разница между шаблоном управления и шаблоном данных в WPF

Ответы:

267

Обычно элемент управления создается сам по себе и не отражает базовые данные. Например, Buttonбизнес-объект не будет привязан - он существует только для того, чтобы на него можно было нажать. А ContentControlили ListBox, как правило, появляются так, что они могут представлять данные для пользователя.

A DataTemplate, следовательно, используется для предоставления визуальной структуры для базовых данных, в то время как a не ControlTemplateимеет ничего общего с базовыми данными и просто предоставляет визуальную компоновку для самого элемента управления.

A ControlTemplateобычно будет содержать только выражения, привязывающие к свойствам самого элемента TemplateBindingуправления, тогда как a DataTemplateбудет содержать стандартные выражения Binding, привязывающие к свойствам его DataContext(объект бизнес / домен или модель представления).

Мэтт Гамильтон
источник
21
Это имело смысл? Думаю, я пытаюсь объяснить философские различия, а не технические.
Мэтт Гамильтон
110

Очень в основном ControlTemplateописывает, как отображать элемент управления, а DataTemplateописывает, как отображать данные.

Например:

A Labelявляется элементом управления и будет включать в себя элемент, ControlTemplateкоторый говорит, что Labelдолжен отображаться с использованием Borderнекоторого содержимого (a DataTemplateили другого элемента управления).

CustomerКласс данные и будет отображаться с помощью DataTemplateкоторого можно было сказать , чтобы отобразить Customerтип в качестве StackPanelсодержащих два TextBlocksодин , показывающего имени , а другие отображаются номер телефона. Может быть полезно отметить, что все классы отображаются с использованием DataTemplates, вы просто будете использовать шаблон по умолчанию, который TextBlockсо Textсвойством, установленным в результате метода объекта ToString.

Брайан Андерсон
источник
Проголосовал за простоту описания. Очень признателен.
Пит Магсиг
31

У Troels Larsen есть хорошее объяснение на форуме MSDN

<Window x:Class="WpfApplication7.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <DataTemplate x:Key="ButtonContentTemplate">
      <StackPanel Orientation="Horizontal">
        <Grid Height="8" Width="8">
          <Path HorizontalAlignment="Stretch" 
           Margin="0,0,1.8,1.8" 
           VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 
           Data="M0.5,5.7 L0.5,0.5 L5.7,0.5"/>
          <Path HorizontalAlignment="Stretch" 
           Margin="2,3,0,0" 
           VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 
           Data="M3.2,7.5 L7.5,7.5 L7.5,3.5"/>
          <Path HorizontalAlignment="Stretch" 
           Margin="1.2,1.4,0.7,0.7" 
           VerticalAlignment="Stretch" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF000000" 
           Data="M2.5,2.5 L7.5,7.5"/>
          <Path HorizontalAlignment="Stretch" 
           Margin="1.7,2.0,1,1" 
           VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 
           Data="M3,7.5 L7.5,7.5 L7.5,3.5"/>
          <Path HorizontalAlignment="Stretch" 
           Margin="1,1,1,1" 
           VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 
           Data="M1.5,6.5 L1.5,1 L6.5,1.5"/>
        </Grid>
        <ContentPresenter Content="{Binding}"/>
      </StackPanel>
    </DataTemplate>
    <ControlTemplate TargetType="Button" x:Key="ButtonControlTemplate">
      <Grid>
        <Ellipse Fill="{TemplateBinding Background}"/>
        <ContentPresenter HorizontalAlignment="Center"
              VerticalAlignment="Center"/>
      </Grid>
    </ControlTemplate>
  </Window.Resources>
  <StackPanel>
    <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="1"/>
    <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="2"/>
    <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="3"/>
  </StackPanel>
</Window>

(Шаблоны явно украдены у http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx и http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate% 28VS.95% 29.aspx соответственно)

В любом случае, ControlTemplate решает, как выглядит сама кнопка, а ContentTemplate решает, как выглядит содержимое кнопки. Таким образом, вы можете привязать контент к одному из ваших классов данных и представить его таким, каким вы его хотели.

onmyway133
источник
19

ControlTemplate: Представляет стиль управления.

DataTemplate: Представляет стиль данных (как бы вы хотели показать свои данные).

Все элементы управления используют шаблон элемента управления по умолчанию, который можно переопределить через свойство шаблона.

Например,
Button шаблон является шаблоном управления. ButtonШаблон содержимого является шаблоном данных.

<Button   VerticalAlignment="Top" >
    <Button.Template>
        <ControlTemplate >
            <Grid>
                <Rectangle Fill="Blue" RadiusX="20" RadiusY="20"/>
                <Ellipse Fill="Red" />
                <ContentPresenter Content="{Binding}">
                    <ContentPresenter.ContentTemplate>
                        <DataTemplate>
                        <StackPanel Orientation="Horizontal" Height="50">
                            <TextBlock Text="Name" Margin="5"/>
                                <TextBox Text="{Binding UserName, Mode=TwoWay}" Margin="5" Width="100"/>
                            <Button Content="Show Name" Click="OnClickShowName" />
                        </StackPanel>
                    </DataTemplate>
                    </ContentPresenter.ContentTemplate>
                </ContentPresenter>
            </Grid>
        </ControlTemplate>
    </Button.Template>
</Button>

public String UserName
{
    get { return userName; }
    set
    {
        userName = value;
        this.NotifyPropertyChanged("UserName");
    }
}
Саид Саад
источник
7

ControlTemplate- Изменение внешнего вида элемента. Например, Buttonможет содержать изображение и текст

DataTemplate - Представление базовых данных с использованием элементов.

Сайед
источник
1

ControlTemplateОпределяет внешний вид, DataTemplateзаменяет внешний вид элемента данных.

Пример: я хочу показать кнопку от прямоугольной формы до формы круга => Шаблон управления.

И если у вас есть сложные объекты для элемента управления, он просто вызывает и показывает ToString(), с помощью которого DataTemplateвы можете получить различные члены и отобразить и изменить их значения объекта данных.

nihnih
источник
0

Все вышеприведенные ответы великолепны, но есть ключевое различие, которое было упущено. Это помогает принимать лучшие решения о том, когда что использовать. Это ItemTemplateсвойство:

  • DataTemplate используется для элементов, которые предоставляют свойство ItemTemplate для замены содержимого его элементов, используя те, которые DataTemplateвы определили ранее в соответствии с привязанными данными через предоставленный вами селектор.

  • Но если ваш контроль не предоставляет такую ​​роскошь для вас, вы все равно можете использовать тот, ContentViewкоторый может отображать его содержимое из предопределенных ControlTemplate. Интересно, что вы можете изменить ControlTemplateсвойство вашего ContentViewво время выполнения. Еще одна вещь, на которую следует обратить внимание: в отличие от элементов управления со ItemTemplateсвойством, у вас не может быть элемента управления TemplateSelectorдля этого (ContentView). Тем не менее, вы все еще можете создавать триггеры для изменения ControlTemplateво время выполнения.

Ashi
источник