WPF中控制模板和数据模板之间的区别


Answers:


267

通常情况下,控件是为自身目的而呈现的,并且不反映基础数据。例如,a Button不会绑定到业务对象-纯粹是在那里,因此可以单击它。甲ContentControl或者ListBox,然而,一般出现,使他们能够对用户显示数据。

DataTemplate因此,A 用于为基础数据提供可视化结构,而A ControlTemplate与基础数据无关,仅为控件本身提供可视化布局。

A ControlTemplate将通常只包含TemplateBinding表达式,并绑定到控件本身的属性,而A DataTemplate将包含标准Binding表达式,并绑定到控件DataContext(业务/域对象或视图模型)的属性。


21
这有意义吗?我想我想解释的是哲学差异而不是技术差异。
Matt Hamilton 2009年

110

基本上,a ControlTemplate描述了如何显示控件,而a DataTemplate描述了如何显示数据。

例如:

A Label是一个控件,将包含一个ControlTemplate,其中表示Label应该使用Border某些Content(一个DataTemplate或另一个控件)周围的来显示。

一个Customer类是Data,将使用来显示DataTemplate,可以说将其显示Customer为一个StackPanel包含两个的类型,TextBlocks一个显示名称,另一个显示电话号码。注意,所有类都使用来显示DataTemplates,您可能会有所帮助,您通常只会使用默认模板,该模板TextBlockText属性设置为Object ToString方法的结果。


为简化描述投票。非常感激。
Pete Magsig

31

Troels LarsenMSDN论坛上有一个很好的解释

<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.aspxhttp://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate%28VS.95%29.aspx 分别)

无论如何,ControlTemplate决定按钮本身的外观,而ContentTemplate决定按钮内容的外观。因此,您可以将内容绑定到其中一个数据类,并根据需要显示它本身。


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即可获取各种成员并显示和更改数据对象的值。


0

以上所有答案都很不错,但是有一个关键的区别被遗漏了。这有助于更好地决定何时使用什么。它是ItemTemplate属性:

  • DataTemplate用于为元素提供ItemTemplate属性,以便您DataTemplate通过提供的选择器根据绑定数据使用先前定义的s 替换其项目的内容。

  • 但是,如果您的控件没有为您提供这种奢侈,那么您仍然可以使用ContentView可以显示预定义内容的控件ControlTemplate。有趣的是,您可以在运行时更改ControlTemplate属性ContentView。需要注意的另一点是,与具有ItemTemplate属性的控件不同,您不能TemplateSelector为此(ContentView)控件使用。但是,您仍然可以创建触发器以ControlTemplate在运行时更改。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.