Como criar um estilo para um controle (WPF .NET)
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 pensar em um Style como uma maneira conveniente de aplicar um conjunto de valores de propriedade a um ou mais elementos. Você pode usar um estilo em qualquer elemento que seja derivado 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 poderá ser usado somente nesse arquivo XAML. Para obter mais informações sobre regras de escopo para recursos, consulte Visão geral de 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 atributo TargetType
. O estilo definirá o FontSize para 15
e o FontWeight para ExtraBold
. Adicione um <Setter>
para cada propriedade que o estilo altera.
Aplicar um estilo implicitamente
Um Style é uma maneira conveniente de aplicar um conjunto de valores de propriedade a mais de um elemento. Por exemplo, considere os seguintes elementos TextBlock e sua aparência padrão em uma janela.
<StackPanel>
<TextBlock>My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>
Você pode alterar a aparência padrão definindo propriedades, como FontSize e FontFamily, em cada elemento TextBlock diretamente. No entanto, se quiser que seus elementos TextBlock compartilhem algumas propriedades, você pode criar um Style na seção Resources
do seu 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 se define a TargetType do seu estilo para o tipo TextBlock e omite o atributo x:Key
, o estilo é aplicado a todos os elementos TextBlock dentro do escopo do estilo, que geralmente é o próprio arquivo XAML.
Agora, os elementos TextBlock aparecem da seguinte forma.
Aplicar um estilo explicitamente
Se você adicionar um atributo x:Key
com valor ao estilo, o estilo não será mais aplicado implicitamente a todos os elementos do TargetType. Apenas os elementos que fazem referência explícita ao estilo terão o estilo aplicado a eles.
Aqui está o estilo da seção anterior, mas declarado com o atributo x:Key
.
<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 no 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 elemento TextBlock 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 declarava o atributo x:Key
, ou seja, o único elemento afetado pelo estilo é aquele que fez referência ao estilo diretamente.
de bloco de texto
Uma vez que um estilo é aplicado, explícita ou implicitamente, ele fica selado e não pode ser alterado. Se você quiser alterar um estilo que foi aplicado, crie um novo estilo para substituir o existente. Para obter mais informações, consulte a propriedade IsSealed.
Você pode criar um objeto que escolhe um estilo para aplicar com base na lógica personalizada. Para obter um exemplo, consulte o exemplo fornecido para a classe StyleSelector.
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 Style do elemento. Os itens em uma coleção de recursos são do tipo Object. Portanto, você deve converter o estilo recuperado para um System.Windows.Style antes de atribuí-lo à propriedade Style
. Por exemplo, o código a seguir define o estilo de um TextBlock
chamado textblock1
para o estilo definido TitleText
.
textblock1.Style = (Style)Resources["TitleText"];
textblock1.Style = CType(Resources("TitleText"), Windows.Style)
Estender um estilo
Talvez você queira que seus dois elementos TextBlock compartilhem alguns valores de propriedade, como o FontFamily e o HorizontalAlignmentcentrado. 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, como 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 estilo TextBlock
agora está centralizado, usa uma fonte Comic Sans MS
com um tamanho de 26
e a cor de primeiro plano definida para o LinearGradientBrush mostrado no exemplo. Note que ele substitui o valor FontSize do estilo base. Se houver mais de um Setter apontando para a mesma propriedade em um Style, a Setter
declarada por último terá precedência.
A seguir mostra como são os elementos TextBlock agora:
Este estilo TitleText
estende o estilo que foi criado para o tipo TextBlock, 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 chamado Header1
e você quisesse estender esse estilo, usaria BasedOn="{StaticResource Header1}"
.
Relação entre a propriedade TargetType e o atributo x:Key
Como mostrado anteriormente, definir a propriedade TargetType como TextBlock
sem atribuir o estilo a x:Key
faz com que o estilo seja aplicado a todos os elementos TextBlock. Neste caso, o x:Key
está implicitamente definido como {x:Type TextBlock}
. Isso significa que, se você definir explicitamente o valor x:Key
para algo diferente de {x:Type TextBlock}
, o Style não será aplicado a todos os elementos TextBlock
automaticamente. Em vez disso, você deve aplicar o estilo (usando o valor x:Key
) aos elementos TextBlock
explicitamente. Se seu estilo estiver na seção de recursos e você não definir a propriedade TargetType
em seu estilo, deverá definir o atributo x:Key
.
Além de fornecer um valor padrão para o x:Key
, a propriedade TargetType
especifica o tipo ao qual as propriedades setter se aplicam. Se você não especificar um TargetType
, deverá qualificar as propriedades em seus objetos Setter 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 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.
Ver também
.NET Desktop feedback