Styling and Templating

Windows Presentation Foundation (WPF)modelagem e os estilos consultem um conjunto de recursos (estilos, modelos, disparadores e storyboards) que permitem que os desenvolvedores e designers para criar efeitos visualmente atraentes e criar uma aparência consistente para seus produtos. Embora os desenvolvedores e/ou os designers podem personalizar a aparência extensivamente em uma base de aplicativo por aplicativo, um forte modelo de modelagem e os estilos é necessário para permitir o compartilhamento da aparência dentro e entre aplicativos e manutenção. Windows Presentation Foundation (WPF)Fornece um modelo.

Outro recurso de WPF modelo de estilo é a separação da apresentação e lógica. Isso significa que os designers podem trabalhar na aparência de um aplicativo usando somente XAML ao mesmo tempo em que os desenvolvedores trabalham a lógica de programação usando o C# ou Visual Basic.

This overview focuses on the styling and templating aspects of the application and does not discuss any data binding concepts. For information about data binding, see Revisão de Associação de Dados.

In addition, it is important to understand resources, which are what enable styles and templates to be reused. Para obter mais informações sobre recursos, consulte Visão geral sobre Recursos.

Este tópico contém as seguintes seções.

  • Exemplo de modelagem e os estilos
  • Style Basics
  • Data Templates
  • Control Templates
  • Triggers
  • Shared Resources and Themes
  • Tópicos relacionados

Exemplo de modelagem e os estilos

Os exemplos de código usados nesta visão geral baseiam-se em uma amostra de foto simples mostrada na ilustração a seguir:

ListView com estilo

Esse exemplo simples de fotos usa modelos e estilos para criar uma experiência de usuário visualmente atraente. O exemplo tem dois TextBlock elementos e um ListBox controle que está acoplado a uma lista de imagens. Para obter o exemplo completo, consulte Introdução aos estilos e modelos de exemplo.

Style Basics

You can think of a Style as a convenient way to apply a set of property values to more than one element. Por exemplo, considere o seguinte TextBlock elementos e sua aparência padrão:

<TextBlock>My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>

Captura de tela de exemplo de aplicação de estilo

Você pode alterar a aparência padrão, definindo propriedades, como FontSize e FontFamily, em cada TextBlock elemento diretamente. However, if you want your TextBlock elements to share some properties, you can create a Style in the Resources section of your XAML file, as shown here:

<Window.Resources>


...


<!--A Style that affects all TextBlocks-->
<Style TargetType="TextBlock">
  <Setter Property="HorizontalAlignment" Value="Center" />
  <Setter Property="FontFamily" Value="Comic Sans MS"/>
  <Setter Property="FontSize" Value="14"/>
</Style>


...


</Window.Resources>

When you set the TargetType of your style to the TextBlock type, the style is applied to all the TextBlock elements in the window.

Now the TextBlock elements appear as follows:

Captura de tela de exemplo de aplicação de estilo

Extending Styles

Perhaps you want your two TextBlock elements to share some property values, such as the FontFamily and the centered HorizontalAlignment, but you also want the text "My Pictures" to have some additional properties. You can do that by creating a new style that is based on the first style, as shown here:

<Window.Resources>


...


<!--A Style that extends the previous TextBlock Style-->
<!--This is a "named style" with an x:Key of TitleText-->
<Style BasedOn="{StaticResource {x:Type TextBlock}}"
       TargetType="TextBlock"
       x:Key="TitleText">
  <Setter Property="FontSize" Value="26"/>
  <Setter Property="Foreground">
  <Setter.Value>
      <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
        <LinearGradientBrush.GradientStops>
          <GradientStop Offset="0.0" Color="#90DDDD" />
          <GradientStop Offset="1.0" Color="#5BFFFF" />
        </LinearGradientBrush.GradientStops>
      </LinearGradientBrush>
    </Setter.Value>
  </Setter>
</Style>


...


</Window.Resources>

Observe que o estilo anterior é fornecido um x:Key. To apply the style, you set the Style property on your TextBlock to the x:Key value, as shown here:

<TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>

This TextBlock style now has a HorizontalAlignment value of Center, a FontFamily value of Comic Sans MS, a FontSize value of 26, and a Foreground value set to the LinearGradientBrush shown in the example. Observe que ela substitui o FontSize o valor do estilo base. If there is more than one Setter setting the same property in a Style, the Setter that is declared last takes precedence.

The following shows what the TextBlock elements now look like:

TextBlocks com estilo

This TitleText style extends the style that has been created for the TextBlock type. You can also extend a style that has an x:Key by using the x:Key value. For an example, see the example provided for the BasedOn property.

Relationship of the TargetType Property and the x:Key Attribute

As shown in the first example, setting the TargetType property to TextBlock without assigning the style an x:Key causes the style to be applied to all TextBlock elements. In this case, the x:Key is implicitly set to {x:Type TextBlock}. This means that if you explicitly set the x:Key value to anything other than {x:Type TextBlock}, the Style is not applied to all TextBlock elements automatically. Instead, you must apply the style (by using the x:Key value) to the TextBlock elements explicitly. If your style is in the resources section and you do not set the TargetType property on your style, then you must provide an x:Key.

In addition to providing a default value for the x:Key, the TargetType property specifies the type to which setter properties apply. Se você não especificar um TargetType, você deve qualificar as propriedades no seu Setter objetos com um nome de classe usando a sintaxe Property="ClassName.Property". For example, instead of setting Property="FontSize", you must set Property to "TextBlock.FontSize" or "Control.FontSize".

Also note that many WPF controls consist of a combination of other WPF controls. If you create a style that applies to all controls of a type, you might get unexpected results. Por exemplo, se você criar um estilo que destinos o TextBlock Digite em um Window, o estilo é aplicado a todos os TextBlock controles na janela, mesmo se o TextBlock é parte de outro controle, como um ListBox.

Styles and Resources

You can use a style on any element that derives from FrameworkElement or FrameworkContentElement. A maneira mais comum para declarar um estilo é como um recurso na Resources seção em um XAML o arquivo, conforme mostrado nos exemplos anteriores. Because styles are resources, they obey the same scoping rules that apply to all resources; where you declare a style affects where the style can be applied. Por exemplo, se você declarar o estilo no elemento raiz de sua definição de aplicativo XAML o arquivo, o estilo pode ser usado em qualquer lugar no aplicativo. If you create a navigation application and declare the style in one of the application's XAML files, the style can be used only in that XAML file. Para obter mais informações sobre regras de recursos de escopo, consulte Visão geral sobre Recursos.

In addition, you can find more information about styles and resources in Shared Resources and Themes later in this overview.

Setting Styles Programmatically

To assign a named style to an element programmatically, get the style from the resources collection and assign it to the element's Style property. Observe que os itens em uma coleção de recursos são do tipo Object. Portanto, você deve converter o estilo recuperado para um Style antes de atribuí-lo para o Style propriedade. For example, to set the defined TitleText style on a TextBlock named textblock1, do the following:

textblock1.Style = CType(Me.Resources("TitleText"), Style)
textblock1.Style = (Style)(this.Resources["TitleText"]);

Note that once a style has been applied, it is sealed and cannot be changed. If you want to dynamically change a style that has already been applied, you must create a new style to replace the existing one. For more information, see the IsSealed property.

You can create an object that chooses a style to apply based on custom logic. For an example, see the example provided for the StyleSelector class.

Bindings, Dynamic Resources, and Event Handlers

Note that you can use the Setter.Value property to specify a Ligação de marcação de extensão or a Extensão de marcação DynamicResource. For more information, see the examples provided for the Setter.Value property.

Até então, essa visão geral discute somente o uso de setters para definir o valor da propriedade. You can also specify event handlers in a style. For more information, see EventSetter.

Data Templates

Este aplicativo de exemplo, há um ListBox controle está acoplado a uma lista de fotos:

<ListBox ItemsSource="{Binding Source={StaticResource MyPhotos}}"
         Background="Silver" Width="600" Margin="10" SelectedIndex="0"/>

This ListBox currently looks like the following:

ListBox antes da aplicação de modelo

A maioria dos controles têm algum tipo de conteúdo e esse conteúdo freqüentemente vem de dados que você está ligando. In this sample, the data is the list of photos. In WPF, you use a DataTemplate to define the visual representation of data. Basically, what you put into a DataTemplate determines what the data looks like in the rendered application.

In our sample application, each custom Photo object has a Source property of type string that specifies the file path of the image. Currently, the photo objects appear as file paths.

For the photos to appear as images, you create a DataTemplate as a resource:

<Window.Resources>


...


<!--DataTemplate to display Photos as images
    instead of text strings of Paths-->
<DataTemplate DataType="{x:Type local:Photo}">
  <Border Margin="3">
    <Image Source="{Binding Source}"/>
  </Border>
</DataTemplate>


...


</Window.Resources>

Notice that the DataType property is very similar to the TargetType property of the Style. Se sua DataTemplate está na seção recursos, quando você especifica o DataType propriedade para um tipo e não o atribuir um x:Key, o DataTemplate é aplicada sempre que esse tipo é exibido. You always have the option to assign the DataTemplate with an x:Key and then set it as a StaticResource for properties that take DataTemplate types, such as the ItemTemplate property or the ContentTemplate property.

Essentially, the DataTemplate in the above example defines that whenever there is a Photo object, it should appear as an Image within a Border. With this DataTemplate, our application now looks like this:

Imagem fotográfica

The data templating model provides other features. For example, if you are displaying collection data that contains other collections using a HeaderedItemsControl type such as a Menu or a TreeView, there is the HierarchicalDataTemplate. Another data templating feature is the DataTemplateSelector, which allows you to choose a DataTemplate to use based on custom logic. For more information, see Visão geral sobre Templating de dados, which provides a more in-depth discussion of the different data templating features.

Control Templates

In WPF, the ControlTemplate of a control defines the appearance of the control. You can change the structure and appearance of a control by defining a new ControlTemplate for the control. Em muitos casos, isso oferece flexibilidade suficiente para que você não precise escrever seus próprios controles personalizados. For more information, see Personalizando a aparência de um controle existente, criando um ControlTemplate..

Triggers

Um disparador define propriedades ou inicia ações, como, por exemplo, uma animação, quando um valor de propriedade alterado ou quando um evento é gerado. Style, ControlTemplate, and DataTemplate all have a Triggers property that can contain a set of triggers. Existem vários tipos de disparadores.

Property Triggers

A Trigger que a propriedade de conjuntos de valores ou inicia ações com base no valor de uma propriedade é chamado um disparador de propriedade.

Para demonstrar como usar disparadores de propriedade, você pode fazer cada ListBoxItem parcialmente transparente, a menos que ele está selecionado. The following style sets the Opacity value of a ListBoxItem to 0.5. When the IsSelected property is true, however, the Opacity is set to 1.0:

<Style TargetType="ListBoxItem">
  <Setter Property="Opacity" Value="0.5" />
  <Setter Property="MaxHeight" Value="75" />
  <Style.Triggers>
    <Trigger Property="IsSelected" Value="True">
        <Setter Property="Opacity" Value="1.0" />
    </Trigger>


...


  </Style.Triggers>
</Style>

This example uses a Trigger to set a property value, but note that the Trigger class also has the EnterActions and ExitActions properties that enable a trigger to perform actions.

Observe que o MaxHeight propriedade da ListBoxItem é definida como 75. Na ilustração a seguir, o terceiro item é o item selecionado:

ListView com estilo

EventTriggers and Storyboards

Another type of trigger is the EventTrigger, which starts a set of actions based on the occurrence of an event. For example, the following EventTrigger objects specify that when the mouse pointer enters the ListBoxItem, the MaxHeight property animates to a value of 90 over a 0.2 second period. When the mouse moves away from the item, the property returns to the original value over a period of 1 second. Note how it is not necessary to specify a To value for the MouseLeave animation. This is because the animation is able to keep track of the original value.

        <EventTrigger RoutedEvent="Mouse.MouseEnter">
          <EventTrigger.Actions>
            <BeginStoryboard>
              <Storyboard>
                <DoubleAnimation
                  Duration="0:0:0.2"
                  Storyboard.TargetProperty="MaxHeight"
                  To="90"  />
              </Storyboard>
            </BeginStoryboard>
          </EventTrigger.Actions>
        </EventTrigger>
        <EventTrigger RoutedEvent="Mouse.MouseLeave">
          <EventTrigger.Actions>
            <BeginStoryboard>
              <Storyboard>
                <DoubleAnimation
                  Duration="0:0:1"
                  Storyboard.TargetProperty="MaxHeight"  />
              </Storyboard>
            </BeginStoryboard>
          </EventTrigger.Actions>
        </EventTrigger>

Para obter mais informações, consulte o Visão geral sobre Storyboards.

Na ilustração a seguir, o mouse está apontando para o terceiro item:

Captura de tela de exemplo de aplicação de estilo

MultiTriggers, DataTriggers, and MultiDataTriggers

Além das Trigger e EventTrigger, há outros tipos de disparadores. MultiTriggerpermite que você definir valores de propriedade com base em várias condições. You use DataTrigger and MultiDataTrigger when the property of your condition is data-bound.

Shared Resources and Themes

A typical Windows Presentation Foundation (WPF) application might have multiple user interface (UI) resources that are applied throughout the application. Coletivamente, esse conjunto de recursos pode ser considerado o tema para o aplicativo. Windows Presentation Foundation (WPF)oferece suporte para o usuário de empacotamento recursos de interface (UI) como um tema usando um dicionário de recurso é encapsulado como o ResourceDictionary classe.

Windows Presentation Foundation (WPF)temas são definidos usando o mecanismo de modelagem e os estilos que Windows Presentation Foundation (WPF) expõe para personalizar os elementos visuais do elemento.

Windows Presentation Foundation (WPF) theme resources are stored in embedded resource dictionaries. These resource dictionaries must be embedded within a signed assembly, and can either be embedded in the same assembly as the code itself or in a side-by-side assembly. In the case of PresentationFramework.dll, the assembly which contains Windows Presentation Foundation (WPF) controls, theme resources are in a series of side-by-side assemblies.

O tema torna-se o último local para pesquisar quando estiver procurando o estilo de um elemento. Typically, the search will begin by walking up the element tree searching for an appropriate resource, then look in the application resource collection and finally query the system. Isso dá aos desenvolvedores de aplicativos a oportunidade de redefinir o estilo de qualquer objeto no nível do aplicativo ou a árvore antes de alcançar o tema.

You can define resource dictionaries as individual files that enable you to reuse a theme across multiple applications. You can also create swappable themes by defining multiple resource dictionaries that provide the same types of resources but with different values. Redefining these styles or other resources at the application level is the recommended approach for skinning an application.

To share a set of resources, including styles and templates, across applications, you can create a XAML file and define a ResourceDictionary. Por exemplo, dê uma olhada na ilustração a seguir mostra parte do de estilo com ControlTemplates de exemplo:

Exemplos de modelo de controle

If you look at the XAML files in the sample, you will notice that the files all have the following:

<ResourceDictionary.MergedDictionaries>
  <ResourceDictionary Source="Shared.xaml" />
</ResourceDictionary.MergedDictionaries>

It is the sharing of shared.xaml, which defines a ResourceDictionary that contains a set of style and brush resources that enables the controls in the sample to have a consistent look.

For more information, see Dicionários de Recursos mesclados.

Se você estiver criando um tema para que você controle personalizado, consulte a seção biblioteca de controle externos a Visão geral sobre criação de controles.

Consulte também

Tarefas

Como: Localizar elementos ControlTemplate gerado

Como: Encontrar Elemento DataTemplate-Generated

Conceitos

Pack URIs in WPF