Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O objetivo deste passo a passo é aprender a criar um botão animado para uso em um aplicativo 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 do botão da declaração do botão. Este passo a passo é escrito inteiramente em Extensible Application Markup Language (XAML).
Importante
Este passo a passo orienta você pelas etapas para criar o aplicativo digitando ou copiando e colando Extensible Application Markup Language (XAML) no Visual Studio. Se 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 concluídos.
Criar botões básicos
Vamos começar criando um novo projeto e adicionando alguns botões à janela.
Para criar um novo projeto WPF e adicionar botões à janela
Inicie o Visual Studio.
Crie um novo projeto WPF: No menu Arquivo , aponte para Novo e clique em Projeto. Encontre 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 que você precisa 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 elemento Grid e acrescente alguns botões à página de Marcação de Aplicações Extensível (XAML) digitando ou copiando e colando o código realçado abaixo 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ê 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 as propriedades dos botões para todo o aplicativo. Os recursos do aplicativo são conceitualmente semelhantes às folhas de estilo em cascata (CSS) externas para páginas da Web; no entanto, os recursos são muito mais poderosos do que as Folhas de Estilo em Cascata (CSS), como você verá no final deste passo a passo. Para saber mais sobre recursos, consulte Recursos XAML.
Para usar estilos para definir propriedades básicas nos botões
Defina um bloco Application.Resources: Abra app.xaml e adicione a seguinte marcação realçada se 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 onde você define o recurso. A definição de recursos no
Application.Resources
arquivo app.xaml permite que o recurso seja usado de qualquer lugar no aplicativo. Para saber mais sobre como definir o escopo de seus recursos, consulte Recursos XAML.Crie um estilo e defina valores de propriedade básica com ele: Adicione a seguinte marcação ao
Application.Resources
bloco . Essa marcação cria um Style que se aplica a todos os botões do aplicativo, definindo o Width dos botões como 90 e o Margin para 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 no aplicativo tem uma largura de 90 e uma margem de 10. Se você pressionar F5 para executar o aplicativo, você 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, especificando valores de propriedade complexos e até mesmo usando estilos como entrada para outros estilos. Para obter mais informações, consulte Styling and Templating.
Defina um valor de propriedade de estilo como um recurso: Os recursos permitem uma maneira simples de reutilizar objetos e valores comumente definidos. É especialmente útil definir valores complexos usando recursos para tornar seu código mais modular. Adicione a seguinte marcação realçada a 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 sob o
Application.Resources
bloco , você criou um recurso chamado "GrayBlueGradientBrush". Este recurso define um gradiente horizontal. Esse recurso pode ser usado como um valor de propriedade de qualquer lugar na aplicação, inclusive dentro do configurador 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. Deve ter um aspeto semelhante ao seguinte:
Criar um modelo que define a aparência do botão
Nesta seção, você cria 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 única.
Até agora, o controle de como os botões parecem no aplicativo tem sido limitado a alterar as propriedades do botão. E se você quiser fazer mudanças mais radicais na aparência do botão? Os modelos permitem um controle poderoso sobre a apresentação de um objeto. Como os modelos podem ser usados dentro de 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
Configurar o template: Uma vez que controlos como Button têm uma propriedade Template, pode definir o valor da propriedade do template da mesma forma que os outros valores de propriedade que definimos num Style usando um Setter. Adicione a seguinte marcação realçada ao estilo do 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, o utilizador precisa definir o modelo. Adicione a seguinte marcação realçada. Esta marcação especifica dois Rectangle elementos com arestas arredondadas, seguidos por um DockPanel. O DockPanel é usado para hospedar o ContentPresenter do botão. A 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 do 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. Deve ter um aspeto semelhante ao seguinte:
Adicione um efeito de vidro ao modelo: Em seguida, você adicionará o copo. Primeiro, você cria alguns recursos que criam um efeito de gradiente de vidro. Adicione estes recursos de gradiente em qualquer lugar dentro do
Application.Resources
bloco :<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 seguinte 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> </Setter.Value>
Observe que o Opacity do retângulo com a
x:Name
propriedade de "glassCube" é 0, portanto, quando você executa a amostra, você não vê o retângulo de vidro sobreposto na parte superior. Isso ocorre porque mais tarde adicionaremos gatilhos ao modelo para quando o usuário interage com o botão. No entanto, você pode ver como o botão se parece 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 interação de 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, click e assim por diante) é definir gatilhos dentro do seu modelo ou estilo. Para criar um Trigger, defina uma "condição" de propriedade como: O valor da propriedade button 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
Adicione gatilhos de modelo: Adicione a marcação realçada ao seu 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>
Adicione os 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 ver o efeito enquanto você 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 ganha foco enquanto o último o perde.
Adicionar animações paraMouseEntereMouseLeave: Em seguida, adicionamos animações aos gatilhos. Adicione a seguinte marcação em qualquer lugar dentro do
ControlTemplate.Triggers
bloco .<!-- 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 encolhe quando o ponteiro do mouse se move sobre o botão e retorna ao tamanho normal quando o ponteiro sai.
Há duas animações que são acionadas quando o ponteiro passa sobre o botão (MouseEnter o evento é acionado). Essas animações encolhem o retângulo de vidro ao longo dos eixos X e Y. Observe as propriedades dos elementos DoubleAnimation — Duration e By. O Duration especifica que a animação ocorre ao longo de meio segundo, e By especifica que o vidro diminui em 10%.
O segundo gatilho de evento (MouseLeave) simplesmente interrompe o primeiro gatilho. 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 ao que era antes do ponteiro do mouse se mover 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 clica no botão. Adicione a seguinte marcação em qualquer lugar dentro do
ControlTemplate.Triggers
bloco:<!-- 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ê executou os seguintes exercícios:
Controladas as propriedades básicas dos botões em toda a aplicação usando o Style.
Criou recursos, como gradientes, para usar nos 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.
Ver também
.NET Desktop feedback