Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O objetivo deste passo a passo é aprender a criar um botão animado para uso em um aplicativo do WPF (Windows Presentation Foundation). Este passo a passo usa estilos e um modelo para criar um recurso de botão personalizado que permite a reutilização do código e a separação da lógica de botão da declaração de botão. Este passo a passo é escrito inteiramente em XAML (Extensible Application Markup Language).
Importante
Este passo a passo orienta você pelas etapas para criar o aplicativo digitando ou copiando e colando XAML (Extensible Application Markup Language) no Visual Studio. Se você preferir aprender a usar um designer para criar o mesmo aplicativo, consulte Criar um botão usando o Microsoft Expression Blend.
A figura a seguir mostra os botões finalizados.
Criar botões básicos
Vamos começar criando um novo projeto e adicionando alguns botões à janela.
Para criar um novo projeto do WPF e adicionar botões à janela
Inicie o Visual Studio.
Crie um novo projeto do WPF: No menu Arquivo , aponte para Novo e clique em Projeto. Localize o modelo de Aplicativo do Windows (WPF) e nomeie o projeto como "AnimatedButton". Isso criará o esqueleto para o aplicativo.
Adicione botões padrão básicos: Todos os arquivos necessários para este passo a passo são fornecidos pelo modelo. Abra o arquivo Window1.xaml clicando duas vezes nele no Gerenciador de Soluções. Por padrão, há um Grid elemento em Window1.xaml. Remova o Grid elemento e adicione alguns botões à página XAML (Extensible Application Markup Language) digitando ou copiando e colando o seguinte código realçado em Window1.xaml:
<Window x:Class="AnimatedButton.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="AnimatedButton" Height="300" Width="300" Background="Black"> <!-- Buttons arranged vertically inside a StackPanel. --> <StackPanel HorizontalAlignment="Left"> <Button>Button 1</Button> <Button>Button 2</Button> <Button>Button 3</Button> </StackPanel> </Window>Pressione F5 para executar o aplicativo; você deve ver um conjunto de botões que se parece com a figura a seguir.
Agora que você criou os botões básicos, terminou de trabalhar no arquivo Window1.xaml. O restante do passo a passo se concentra no arquivo app.xaml, definindo estilos e um modelo para os botões.
Definir propriedades básicas
Em seguida, vamos definir algumas propriedades nesses botões para controlar a aparência e o layout do botão. Em vez de definir propriedades nos botões individualmente, você usará recursos para definir propriedades de botão para todo o aplicativo. Os recursos de aplicativo são conceitualmente semelhantes às CSS (Folhas de Estilo em Cascata) externas para páginas da Web; no entanto, os recursos são muito mais poderosos do que CSS (Folhas de Estilo em Cascata), como você verá ao final deste passo a passo. Para saber mais sobre recursos, consulte Recursos XAML.
Para usar estilos para definir propriedades básicas nos botões
Definir um bloco Application.Resources: Abra app.xaml e adicione a seguinte marcação realçada se ela ainda não estiver lá:
<Application x:Class="AnimatedButton.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window1.xaml" > <Application.Resources> <!-- Resources for the entire application can be defined here. --> </Application.Resources> </Application>O escopo do recurso é determinado pelo local em que você define o recurso. Definir recursos no
Application.Resourcesarquivo app.xaml permite que o recurso seja usado em qualquer lugar do aplicativo. Para saber mais sobre como definir o escopo de seus recursos, consulte Recursos XAML.Crie um estilo e defina valores básicos de propriedade com ele: Adicione a marcação a seguir ao
Application.Resourcesbloco. Essa marcação cria um Style que se aplica a todos os botões no aplicativo, definindo os Width botões como 90 e Margin 10:<Application.Resources> <Style TargetType="Button"> <Setter Property="Width" Value="90" /> <Setter Property="Margin" Value="10" /> </Style> </Application.Resources>A TargetType propriedade especifica que o estilo se aplica a todos os objetos do tipo Button. Cada Setter um define um valor de propriedade diferente para o Style. Portanto, neste ponto, cada botão do aplicativo tem uma largura de 90 e uma margem de 10. Se você pressionar F5 para executar o aplicativo, verá a janela a seguir.
Há muito mais que você pode fazer com estilos, incluindo uma variedade de maneiras de ajustar quais objetos são direcionados, especificar valores de propriedade complexos e até mesmo usar estilos como entrada para outros estilos. Para obter mais informações, consulte Estilo e modelagem.
Defina um valor de propriedade de estilo como um recurso: Os recursos permitem uma maneira simples de reutilizar objetos e valores normalmente definidos. É especialmente útil definir valores complexos usando recursos para tornar seu código mais modular. Adicione a marcação realçada a seguir ao app.xaml.
<Application.Resources> <LinearGradientBrush x:Key="GrayBlueGradientBrush" StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="DarkGray" Offset="0" /> <GradientStop Color="#CCCCFF" Offset="0.5" /> <GradientStop Color="DarkGray" Offset="1" /> </LinearGradientBrush> <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" /> <Setter Property="Width" Value="80" /> <Setter Property="Margin" Value="10" /> </Style> </Application.Resources>Diretamente abaixo do bloco
Application.Resources, você criou um recurso chamado "GrayBlueGradientBrush". Esse recurso define um gradiente horizontal. Esse recurso pode ser usado como um valor de propriedade de qualquer lugar no aplicativo, incluindo dentro do definidor de estilo do botão para a propriedade Background. Agora, todos os botões têm um Background valor de propriedade desse gradiente.Pressione F5 para executar o aplicativo. Ele deverá ter a seguinte aparência.
Criar um modelo que define a aparência do botão
Nesta seção, você criará um modelo que personaliza a aparência (apresentação) do botão. A apresentação do botão é composta por vários objetos, incluindo retângulos e outros componentes para dar ao botão uma aparência exclusiva.
Até agora, o controle da aparência dos botões no aplicativo foi limitado à alteração das propriedades do botão. E se você quiser fazer alterações mais radicais na aparência do botão? Os modelos permitem um controle avançado sobre a apresentação de um objeto. Como os modelos podem ser usados em estilos, você pode aplicar um modelo a todos os objetos aos quais o estilo se aplica (neste passo a passo, o botão).
Para usar o modelo para definir a aparência do botão
Configure o modelo: Como controles como Button têm uma propriedade Template, você pode definir o valor da propriedade do modelo assim como os outros valores de propriedade que definimos em um Style usando um Setter. Adicione a marcação realçada a seguir ao seu estilo de botão.
<Application.Resources> <LinearGradientBrush x:Key="GrayBlueGradientBrush" StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="DarkGray" Offset="0" /> <GradientStop Color="#CCCCFF" Offset="0.5" /> <GradientStop Color="DarkGray" Offset="1" /> </LinearGradientBrush> <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" /> <Setter Property="Width" Value="80" /> <Setter Property="Margin" Value="10" /> <Setter Property="Template"> <Setter.Value> <!-- The button template is defined here. --> </Setter.Value> </Setter> </Style> </Application.Resources>Apresentação do botão de alteração: Neste ponto, você precisa definir o modelo. Adicione a marcação realçada a seguir. Essa marcação especifica dois Rectangle elementos com bordas arredondadas, seguidos por um DockPanel. O DockPanel é usado para hospedar o ContentPresenter botão. Um ContentPresenter exibe o conteúdo do botão. Neste passo a passo, o conteúdo é texto ("Botão 1", "Botão 2", "Botão 3"). Todos os componentes de modelo (os retângulos e o DockPanel) são dispostos dentro de um Grid.
<Setter.Value> <ControlTemplate TargetType="Button"> <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True"> <!-- Outer Rectangle with rounded corners. --> <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" /> <!-- Inner Rectangle with rounded corners. --> <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Transparent" StrokeThickness="20" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" /> <!-- Present Content (text) of the button. --> <DockPanel Name="myContentPresenterDockPanel"> <ContentPresenter x:Name="myContentPresenter" Margin="20" Content="{TemplateBinding Content}" TextBlock.Foreground="Black" /> </DockPanel> </Grid> </ControlTemplate> </Setter.Value>Pressione F5 para executar o aplicativo. Ele deverá ter a seguinte aparência.
Adicione um efeito de vidro ao modelo: Em seguida, você adicionará o efeito de vidro. Primeiro, você cria alguns recursos que criam um efeito de gradiente de vidro. Adicione estes recursos de gradiente em qualquer lugar dentro do
Application.Resourcesbloco:<Application.Resources> <GradientStopCollection x:Key="MyGlassGradientStopsResource"> <GradientStop Color="WhiteSmoke" Offset="0.2" /> <GradientStop Color="Transparent" Offset="0.4" /> <GradientStop Color="WhiteSmoke" Offset="0.5" /> <GradientStop Color="Transparent" Offset="0.75" /> <GradientStop Color="WhiteSmoke" Offset="0.9" /> <GradientStop Color="Transparent" Offset="1" /> </GradientStopCollection> <LinearGradientBrush x:Key="MyGlassBrushResource" StartPoint="0,0" EndPoint="1,1" Opacity="0.75" GradientStops="{StaticResource MyGlassGradientStopsResource}" /> <!-- Styles and other resources below here. -->Esses recursos são usados como o Fill para um retângulo que inserimos no Grid modelo de botão. Adicione a marcação realçada a seguir ao modelo.
<Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True"> <!-- Outer Rectangle with rounded corners. --> <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" /> <!-- Inner Rectangle with rounded corners. --> <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Transparent" StrokeThickness="20" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" /> <!-- Glass Rectangle --> <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0" Fill="{StaticResource MyGlassBrushResource}" RenderTransformOrigin="0.5,0.5"> <Rectangle.Stroke> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.0" Color="LightBlue" /> <GradientStop Offset="1.0" Color="Gray" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Stroke> <!-- These transforms have no effect as they are declared here. The reason the transforms are included is to be targets for animation (see later). --> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform /> <RotateTransform /> </TransformGroup> </Rectangle.RenderTransform> <!-- A BevelBitmapEffect is applied to give the button a "Beveled" look. --> <Rectangle.BitmapEffect> <BevelBitmapEffect /> </Rectangle.BitmapEffect> </Rectangle> <!-- Present Text of the button. --> <DockPanel Name="myContentPresenterDockPanel"> <ContentPresenter x:Name="myContentPresenter" Margin="20" Content="{TemplateBinding Content}" TextBlock.Foreground="Black" /> </DockPanel> </Grid> </ControlTemplate> </Setter.Value>Observe que a propriedade Opacity do retângulo com a
x:Namede "glassCube" é 0, portanto, quando você executa a amostra, não vê o retângulo de vidro sobreposto. Isso ocorre porque, posteriormente, adicionaremos gatilhos ao modelo para quando o usuário interagir com o botão. No entanto, você pode ver a aparência do botão agora alterando o Opacity valor para 1 e executando o aplicativo. Veja a figura a seguir. Antes de prosseguir para a próxima etapa, altere o Opacity de volta para 0.
Criar interatividade para o botão
Nesta seção, você criará gatilhos de propriedade e gatilhos de evento para alterar valores de propriedade e executar animações em resposta a ações do usuário, como mover o ponteiro do mouse sobre o botão e clicar.
Uma maneira fácil de adicionar interatividade (mouse-over, mouse-leave, clique e assim por diante) é definir gatilhos dentro de seu modelo ou estilo. Para criar um Trigger, você define uma propriedade "condição" como: o valor da propriedade do botão IsMouseOver é igual a true. Em seguida, você define setters (ações) que ocorrem quando a condição de gatilho é verdadeira.
Para criar interatividade de botões
Adicionar gatilhos de modelo: Adicione a marcação realçada ao modelo.
<Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True"> <!-- Outer Rectangle with rounded corners. --> <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" /> <!-- Inner Rectangle with rounded corners. --> <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Transparent" StrokeThickness="20" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" /> <!-- Glass Rectangle --> <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0" Fill="{StaticResource MyGlassBrushResource}" RenderTransformOrigin="0.5,0.5"> <Rectangle.Stroke> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.0" Color="LightBlue" /> <GradientStop Offset="1.0" Color="Gray" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Stroke> <!-- These transforms have no effect as they are declared here. The reason the transforms are included is to be targets for animation (see later). --> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform /> <RotateTransform /> </TransformGroup> </Rectangle.RenderTransform> <!-- A BevelBitmapEffect is applied to give the button a "Beveled" look. --> <Rectangle.BitmapEffect> <BevelBitmapEffect /> </Rectangle.BitmapEffect> </Rectangle> <!-- Present Text of the button. --> <DockPanel Name="myContentPresenterDockPanel"> <ContentPresenter x:Name="myContentPresenter" Margin="20" Content="{TemplateBinding Content}" TextBlock.Foreground="Black" /> </DockPanel> </Grid> <ControlTemplate.Triggers> <!-- Set action triggers for the buttons and define what the button does in response to those triggers. --> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value>Adicionar gatilhos de propriedade: Adicione a marcação realçada ao bloco
ControlTemplate.Triggers:<ControlTemplate.Triggers> <!-- Set properties when mouse pointer is over the button. --> <Trigger Property="IsMouseOver" Value="True"> <!-- Below are three property settings that occur when the condition is met (user mouses over button). --> <!-- Change the color of the outer rectangle when user mouses over it. --> <Setter Property ="Rectangle.Stroke" TargetName="outerRectangle" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" /> <!-- Sets the glass opacity to 1, therefore, the glass "appears" when user mouses over it. --> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" /> <!-- Makes the text slightly blurry as though you were looking at it through blurry glass. --> <Setter Property="ContentPresenter.BitmapEffect" TargetName="myContentPresenter"> <Setter.Value> <BlurBitmapEffect Radius="1" /> </Setter.Value> </Setter> </Trigger> <ControlTemplate.Triggers/>Pressione F5 para executar o aplicativo e veja o efeito enquanto executa o ponteiro do mouse sobre os botões.
Adicione um gatilho de foco: Em seguida, adicionaremos alguns setters semelhantes para lidar com o caso quando o botão tiver foco (por exemplo, depois que o usuário clicar nele).
<ControlTemplate.Triggers> <!-- Set properties when mouse pointer is over the button. --> <Trigger Property="IsMouseOver" Value="True"> <!-- Below are three property settings that occur when the condition is met (user mouses over button). --> <!-- Change the color of the outer rectangle when user mouses over it. --> <Setter Property ="Rectangle.Stroke" TargetName="outerRectangle" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" /> <!-- Sets the glass opacity to 1, therefore, the glass "appears" when user mouses over it. --> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" /> <!-- Makes the text slightly blurry as though you were looking at it through blurry glass. --> <Setter Property="ContentPresenter.BitmapEffect" TargetName="myContentPresenter"> <Setter.Value> <BlurBitmapEffect Radius="1" /> </Setter.Value> </Setter> </Trigger> <!-- Set properties when button has focus. --> <Trigger Property="IsFocused" Value="true"> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" /> <Setter Property="Rectangle.Stroke" TargetName="outerRectangle" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" /> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" /> </Trigger> </ControlTemplate.Triggers>Pressione F5 para executar o aplicativo e clique em um dos botões. Observe que o botão permanece realçado depois de clicar nele porque ele ainda tem foco. Se você clicar em outro botão, o novo botão ganhará foco enquanto o último o perde.
Adicionar animações paraMouseEntereMouseLeave: Em seguida, adicionamos algumas animações aos gatilhos. Adicione a marcação a seguir em qualquer lugar dentro do
ControlTemplate.Triggersbloco.<!-- Animations that start when mouse enters and leaves button. --> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <EventTrigger.Actions> <BeginStoryboard Name="mouseEnterBeginStoryboard"> <Storyboard> <!-- This animation makes the glass rectangle shrink in the X direction. --> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" By="-0.1" Duration="0:0:0.5" /> <!-- This animation makes the glass rectangle shrink in the Y direction. --> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" By="-0.1" Duration="0:0:0.5" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <EventTrigger RoutedEvent="Mouse.MouseLeave"> <EventTrigger.Actions> <!-- Stopping the storyboard sets all animated properties back to default. --> <StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard" /> </EventTrigger.Actions> </EventTrigger>O retângulo de vidro diminui quando o ponteiro do mouse se move sobre o botão e retorna de volta ao tamanho normal quando o ponteiro sai.
Há duas animações que são ativadas quando o ponteiro se move sobre o botão (e o evento MouseEnter é acionado). Essas animações reduzem o retângulo de vidro ao longo do eixo X e Y. Observe as propriedades dos elementos DoubleAnimation — Duration e By. O Duration especifica que a animação ocorre em meio segundo, e o By especifica que o vidro diminui em 10%.
O segundo gatilho de evento (MouseLeave) simplesmente interrompe o primeiro. Quando você interrompe um Storyboard, todas as propriedades animadas retornam aos seus valores padrão. Portanto, quando o usuário move o ponteiro para fora do botão, o botão volta para o modo como era antes do ponteiro do mouse ser movido sobre o botão. Para obter mais informações sobre animações, consulte Visão geral da animação.
Adicione uma animação para quando o botão for clicado: A etapa final é adicionar um gatilho para quando o usuário clicar no botão. Adicione a seguinte marcação em qualquer lugar dentro do
ControlTemplate.Triggersbloco:<!-- Animation fires when button is clicked, causing glass to spin. --> <EventTrigger RoutedEvent="Button.Click"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)" By="360" Duration="0:0:0.5" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger>Pressione F5 para executar o aplicativo e clique em um dos botões. Quando você clica em um botão, o retângulo de vidro gira ao redor.
Resumo
Neste passo a passo, você realizou os seguintes exercícios:
Controladas as propriedades básicas dos botões em todo o aplicativo usando o Style.
Recursos como gradientes foram criados para serem usados como valores de propriedade dos Style setters.
Personalizou a aparência dos botões em todo o aplicativo aplicando um modelo aos botões.
Comportamento personalizado para os botões em resposta a ações do usuário (como MouseEnter, MouseLeavee Click) que incluíam efeitos de animação.
Consulte também
- Criar um botão usando o Microsoft Expression Blend
- Estilo e Templatização
- Visão geral da animação
- Visão Geral da Pintura com Cores Sólidas e Gradientes
- Visão geral dos efeitos do bitmap
.NET Desktop feedback