Compartilhar via


Como criar um estilo para um controle

Com o Windows Presentation Foundation (WPF), você pode personalizar a aparência de um controle existente com seu próprio estilo reutilizável. Os estilos podem ser aplicados globalmente ao seu aplicativo, janelas e páginas ou diretamente aos controles.

Criar um estilo

Você pode considerar uma Style maneira conveniente de aplicar um conjunto de valores de propriedade a um ou mais elementos. Você pode usar um estilo em qualquer elemento que deriva de FrameworkElement ou FrameworkContentElement, como um Window ou um Button.

A maneira mais comum de declarar um estilo é como um recurso na seção Resources em um arquivo XAML. Como os estilos são recursos, eles obedecem às mesmas regras de escopo que se aplicam a todos os recursos. Simplificando, onde você declara um estilo afeta onde o estilo pode ser aplicado. Por exemplo, se você declarar o estilo no elemento raiz do arquivo XAML de definição de aplicativo, o estilo poderá ser usado em qualquer lugar do aplicativo.

<Application x:Class="IntroToStylingAndTemplating.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:IntroToStylingAndTemplating"
             StartupUri="WindowExplicitStyle.xaml">
    <Application.Resources>
        <ResourceDictionary>
            
            <Style x:Key="Header1" TargetType="TextBlock">
                <Setter Property="FontSize" Value="15" />
                <Setter Property="FontWeight" Value="ExtraBold" />
            </Style>
            
        </ResourceDictionary>
    </Application.Resources>
</Application>

Se você declarar o estilo em um dos arquivos XAML do aplicativo, o estilo só poderá ser usado nesse arquivo XAML. Para obter mais informações sobre regras de escopo para recursos, consulte Visão geral dos recursos XAML.

<Window x:Class="IntroToStylingAndTemplating.WindowSingleResource"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:IntroToStylingAndTemplating"
        mc:Ignorable="d"
        Title="WindowSingleResource" Height="450" Width="800">
    <Window.Resources>
        
        <Style x:Key="Header1" TargetType="TextBlock">
            <Setter Property="FontSize" Value="15" />
            <Setter Property="FontWeight" Value="ExtraBold" />
        </Style>
        
    </Window.Resources>
    <Grid />
</Window>

Um estilo é composto por <Setter> elementos filho que definem propriedades nos elementos aos quais o estilo é aplicado. No exemplo acima, observe que o estilo está definido para ser aplicado a TextBlock tipos por meio do TargetType atributo. O estilo definirá FontSize para 15 e FontWeight para ExtraBold. Adicione um <Setter> para cada propriedade que o estilo modifica.

Aplicar um estilo implicitamente

A Style é uma maneira conveniente de aplicar um conjunto de valores de propriedade a mais de um elemento. Por exemplo, considere os seguintes TextBlock elementos e sua aparência padrão em uma janela.

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

Estilo da captura de tela mostrado anteriormente

Você pode alterar a aparência padrão definindo propriedades, como FontSize e FontFamily, em cada TextBlock elemento diretamente. No entanto, se você quiser que seus TextBlock elementos compartilhem algumas propriedades, você pode criar uma Style na Resources seção do arquivo XAML, conforme mostrado aqui.

<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>

Quando você define o TargetType do seu estilo como o TextBlock tipo e omite o x:Key atributo, o estilo é aplicado a todos os TextBlock elementos no escopo do estilo, que geralmente é o próprio arquivo XAML.

Agora os TextBlock elementos aparecem da seguinte maneira.

Estilo base de exemplo de captura de tela

Aplicar um estilo explicitamente

Se você adicionar um x:Key atributo com valor ao estilo, o estilo não será mais aplicado implicitamente a todos os elementos de TargetType. Somente os elementos que referenciam explicitamente o estilo terão o estilo aplicado a eles.

Aqui está o estilo da seção anterior, mas declarado com o x:Key atributo.

<Window.Resources>
    <Style x:Key="TitleText" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

Para aplicar o estilo, defina a propriedade Style do elemento para o valor x:Key usando uma extensão de marcação StaticResource, conforme mostrado aqui.

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

Observe que o primeiro TextBlock elemento tem o estilo aplicado a ele enquanto o segundo elemento TextBlock permanece inalterado. O estilo implícito da seção anterior foi alterado para um estilo que declarou o x:Key atributo, ou seja, o único elemento afetado pelo estilo é aquele que fez referência diretamente ao estilo.

Bloco de texto de exemplo de captura de tela de estilo

Depois que um estilo é aplicado, explicitamente ou implicitamente, ele fica lacrado e não pode ser alterado. Se você quiser alterar um estilo que tenha sido aplicado, crie um novo estilo para substituir o existente. Para obter mais informações, consulte a propriedade IsSealed.

Você pode criar um objeto que escolha um estilo a ser aplicado com base na lógica personalizada. Para obter um exemplo, consulte o exemplo fornecido para a StyleSelector classe.

Aplicar um estilo programaticamente

Para atribuir um estilo nomeado a um elemento programaticamente, obtenha o estilo da coleção de recursos e atribua-o à propriedade do Style elemento. Os itens em uma coleção de recursos são do tipo Object. Portanto, você deve converter o estilo recuperado em um System.Windows.Style antes de atribuí-lo à Style propriedade. Por exemplo, o código a seguir define o estilo de um TextBlock nomeado textblock1 para o estilo TitleTextdefinido.

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

Desenvolver um estilo

Talvez você queira que seus dois TextBlock elementos compartilhem alguns valores de propriedade, como o FontFamily e o centralizado HorizontalAlignment. Mas você também deseja que o texto Minhas Imagens tenha algumas propriedades adicionais. Você pode fazer isso criando um novo estilo baseado no primeiro estilo, conforme mostrado aqui.

<Window.Resources>
    <!-- .... other 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>
    
    <!--A Style that extends the previous TextBlock 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>

Em seguida, aplique o estilo a um TextBlock.

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

Esse TextBlock estilo agora é centralizado, usa uma Comic Sans MS fonte com um tamanho de 26, e a cor de primeiro plano definida como a LinearGradientBrush mostrada no exemplo. Observe que substitui o valor de FontSize do estilo base. Se houver mais de um Setter apontando para a mesma propriedade em um Style, o Setter último declarado terá precedência.

O seguinte mostra como os TextBlock elementos agora se parecem:

Blocos de texto estilizados

Esse TitleText estilo estende o estilo que foi criado para o TextBlock tipo, referenciado com BasedOn="{StaticResource {x:Type TextBlock}}". Você também pode estender um estilo que tenha um x:Key usando o x:Key do estilo. Por exemplo, se houvesse um estilo nomeado Header1 e você quisesse estender esse estilo, você usaria BasedOn="{StaticResource Header1}".

Relação da propriedade TargetType e do atributo x:Key

Como mostrado anteriormente, definir a propriedade TargetType para TextBlock sem atribuir o estilo x:Key resulta na aplicação do estilo a todos os elementos TextBlock. Nesse caso, a configuração x:Key é implicitamente ajustada para {x:Type TextBlock}. Isso significa que, se você definir explicitamente o valor de x:Key como algo diferente de {x:Type TextBlock}, o valor de Style não será aplicado automaticamente a todos os elementos TextBlock. Em vez disso, você deve aplicar o estilo (usando o x:Key valor) aos TextBlock elementos explicitamente. Se o seu estilo estiver na seção de recursos e você não definir a TargetType propriedade do seu estilo, deverá definir o x:Key atributo.

Além de fornecer um valor padrão para a x:Keypropriedade, a TargetType propriedade especifica o tipo ao qual as propriedades setter se aplicam. Se você não especificar um TargetType, deverá qualificar as propriedades em seus Setter objetos com um nome de classe usando a sintaxe Property="ClassName.Property". Por exemplo, em vez de definir Property="FontSize", você deve definir Property como "TextBlock.FontSize" ou "Control.FontSize".

Observe também que muitos controles WPF consistem em uma combinação de outros controles do WPF. Se você criar um estilo que se aplique a todos os controles de um tipo, poderá obter resultados inesperados. Por exemplo, se você criar um estilo direcionado ao tipo TextBlock em um Window, o estilo será aplicado a todos os controles TextBlock na janela, mesmo que o TextBlock faça parte de outro controle, como um ListBox.

Consulte também