Różnica między szablonem sterowania a szablonem danych w WPF

Odpowiedzi:

267

Zwykle formant jest renderowany dla samego siebie i nie odzwierciedla podstawowych danych. Na przykład obiekt Buttonnie byłby związany z obiektem biznesowym - jest tam wyłącznie, aby można go było kliknąć. A ContentControllub ListBox, na ogół, pojawiają się, aby móc przedstawić dane dla użytkownika.

A DataTemplatezatem służy do zapewnienia wizualnej struktury bazowych danych, podczas gdy ControlTemplatenie ma nic wspólnego z podstawowymi danymi i po prostu zapewnia wizualny układ samej kontrolki.

A na ControlTemplateogół będzie zawierać tylko TemplateBindingwyrażenia, wiążące się z właściwościami samego formantu, podczas gdy a DataTemplatebędzie zawierało standardowe wyrażenia Binding, wiążące się z właściwościami jego DataContext(obiektu biznesowego / domeny lub modelu widoku).

Matt Hamilton
źródło
21
Czy to ma sens? Chyba staram się wyjaśnić różnice filozoficzne, a nie techniczne.
Matt Hamilton
110

Zasadniczo ControlTemplateopisuje sposób wyświetlania Kontroli, a DataTemplateopisuje sposób wyświetlania Danych.

Na przykład:

A Labeljest formantem, który będzie zawierał komunikat, ControlTemplatektóry Labelpowinien być wyświetlany przy użyciu Borderjakiejś Treści (a DataTemplatelub innej Kontroli).

CustomerKlasa danych i będą wyświetlane za pomocą DataTemplatektórych można powiedzieć, aby wyświetlić Customertyp jako StackPanelzawierający dwie TextBlocksjeden pokazujący nazwę i inne wyświetlanie numeru telefonu. Może to być pomocne, aby pamiętać, że wszystkie klasy są wyświetlane przy użyciu DataTemplates, będzie tylko zazwyczaj użyć domyślnego szablonu, który jest TextBlockz Textwłaściwości zestawu do wyniku obiektu ToStringmetody.

Bryan Anderson
źródło
Zagłosowano za prostotę opisu. Bardzo mile widziane.
Pete Magsig
31

Troels Larsen ma dobre wyjaśnienie na forum 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>

(Szablony rażąco skradzione z http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx i http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate% 28VS.95% odpowiednio 29.aspx )

W każdym razie ControlTemplate decyduje o wyglądzie samego przycisku, a ContentTemplate decyduje o wyglądzie zawartości przycisku. Możesz więc powiązać zawartość z jedną z klas danych i sprawić, by prezentowała się tak, jak chcesz.

onmyway133
źródło
19

ControlTemplate: Reprezentuje styl kontroli.

DataTemplate: Reprezentuje styl danych (Jak chcesz pokazać swoje dane).

Wszystkie formanty używają domyślnego szablonu kontroli, który można zastąpić za pomocą właściwości szablonu.

Na przykład
Button szablon jest szablonem sterującym. Buttonszablon treści to szablon danych

<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");
    }
}
powiedział saad
źródło
7

ControlTemplate- Zmiana wyglądu elementu. Na przykład Buttonmoże zawierać obraz i tekst

DataTemplate - Reprezentowanie podstawowych danych za pomocą elementów.

Syed
źródło
1

ControlTemplateOKREŚLA wygląd wizualny, WYMIENIA wygląd DataTemplatezewnętrzny elementu danych.

Przykład: Chcę pokazać przycisk z formularza prostokątnego do koła => Szablon kontrolny.

A jeśli masz złożone obiekty do kontroli, to po prostu wywołuje i pokazuje ToString(), dzięki DataTemplateczemu możesz uzyskać różnych członków oraz wyświetlać i zmieniać ich wartości obiektu danych.

nihnih
źródło
0

Wszystkie powyższe odpowiedzi są świetne, ale brakuje istotnej różnicy. Pomaga to podejmować lepsze decyzje o tym, kiedy z czego korzystać. Jest ItemTemplatewłasnością:

  • DataTemplate jest używany w przypadku elementów, które zapewniają właściwość ItemTemplate w celu zastąpienia zawartości jego elementów za pomocą DataTemplates zdefiniowanych wcześniej zgodnie z powiązanymi danymi za pomocą podanego selektora.

  • Ale jeśli twoja kontrola nie zapewni ci tego luksusu , nadal możesz użyć takiego, ContentViewktóry może wyświetlać jego zawartość z góry określonych ControlTemplate. Co ciekawe, możesz zmienić ControlTemplatewłaściwość swojego ContentVieww czasie wykonywania. Trzeba jeszcze zauważyć, że w przeciwieństwie do kontrolek z ItemTemplatewłaściwością, nie można mieć TemplateSelectorkontrolki (ContentView). Nadal można jednak tworzyć wyzwalacze, które zmieniają ControlTemplateśrodowisko wykonawcze.

Ashi
źródło