Demonstra Passo a passo: Criar um botão usando XAML
O objetivo dessa explicação passo a passo é aprender a criar um botão animado para uso em um aplicativo Windows Presentation Foundation (WPF). Essa explicação passo a passo usa estilos e um modelo para criar um recurso de botão personalizado que permite a reutilização de código e separação da lógica do botão da declaração do botão. Essa explicação passo a passo é escrita inteiramente em Extensible Application Markup Language (XAML).
Observação importante: |
---|
Isso explicação passo a passo orienta você nas etapas Para criar o aplicativo digitando ou copiando e colando Extensible Application Markup Language (XAML) para o Microsoft Visual Studio. Se preferir aprender a usar uma ferramenta de design (Microsoft Expression Blend) para criar o mesmo aplicativo, consulte Demonstra Passo a passo: Create a Button by Using 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 Visual Studio.
Crie um novo projeto do WPF: Sobre o Arquivo , aponte para Novoe, em seguida, clicar Projeto. Localizar o aplicativos do Windows (WPF) modelo e o nome do projeto "AnimatedButton". Isso criará o esqueleto para o aplicativo.
Adicione botões padrão básico: Todos os arquivos que necessários para esta explicação passo a passo são fornecidos pelo modelo. Abra o arquivo Window1.xaml por duplo clique no Gerenciador de Soluções. Por padrão, há um elemento Grid em Window1.xaml. Remova o elemento Grid e adicione alguns botões à página Extensible Application Markup Language (XAML) digitando ou copiando e colando o seguinte código realçado para Window1.xaml:
<Window x:Class="AnimatedButton.Window1" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://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 parecido com a figura a seguir.
Agora que você criou os botões básicos, você terminou de trabalhar no arquivo Window1.xaml. O restante da explicação passo a passo enfoca o arquivo app.xaml, definindo os 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 de botões individualmente, você usará recursos para definir propriedades de botão para todo o aplicativo. Recursos de aplicativo são conceitualmente semelhantes a Folhas de Estilos em Cascata (CSS) externos para páginas da Web; no entanto, recursos são muito mais potentes do que Folhas de Estilos em Cascata (CSS), como você verá no final dessa explicação passo a passo. Para saber mais sobre recursos, consulte Visão geral sobre Recursos.
Para usar estilos para configurar as propriedades básicas nos botões
Defina um bloco aplicativo.Recursos: Abra app.xaml e adicione a seguinte marcação realçada caso ele não ainda esteja lá:
<Application x:Class="AnimatedButton.App" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window1.xaml" > <Application.Resources> <!-- Resources for the entire application can be defined here. --> </Application.Resources> </Application>
Escopo de recursos é determinado por onde você define o recurso. Definir recursos em Application.Resoureses no 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 Visão geral sobre Recursos.
Criar um estilo e definir valores de propriedade básico com ele: Adicione a seguinte marcação para o Application.Resources bloco. Este marcação cria um Style que se aplica a todos os botões no aplicativo, definindo Width dos botões como 90 e Margin como 10:
<Application.Resources> <Style TargetType="Button"> <Setter Property="Width" Value="90" /> <Setter Property="Margin" Value="10" /> </Style> </Application.Resources>
A propriedade TargetType especifica que o estilo se aplica a todos os objetos do tipo Button. Cada Setter define um valor de propriedade diferente para o Style. Portanto, neste momento todos os botões no aplicativo tem uma largura de 90 e uma margem de 10. Se você pressionar F5 para executar o aplicativo, você vê a janela seguinte.
Há muito mais que você pode fazer com estilos, incluindo uma variedade de maneiras de fazer ajuste fino de quais objetos servem de alvo, especificando valores complexos de propriedade, e até mesmo usar estilos como entrada para outros estilos. Para obter mais informações, consulte Styling and Templating.
conjunto um valor da propriedade de estilo a um recurso: Recursos permitem que uma forma simples de reutilizar objetos normalmente definidos e valores. Isso é especialmente útil para 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 bloco Application.Resources, 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 no aplicativo, incluindo dentro de configurador de estilo do botão para a propriedade Background. Agora, todos os botões têm um valor de propriedade Background deste gradiente.
Pressione F5 para executar o aplicativo. O código deve se parecer com o 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 de vários objetos, incluindo retângulos e outros componentes para dar uma aparência exclusiva ao botão.
Até o momento, o controle de como botões se parecem no aplicativo esteve restrito a alterar propriedades do botão. E se você quiser fazer alterações mais radicais à aparência do botão? Modelos permitem poderoso controle 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 (nessa explicação passo a passo, o botão).
Para usar o modelo para definir a aparência do botão
conjunto até o modelo: Porque controles como Button ter um Template propriedade, você pode conjunto o valor da propriedade da mesma forma que os outros valores de propriedade estabelecidas no modelo de um Style usando um Setter. Adicione a seguinte marcação realçada ao estilo de seu 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>
Altere a apresentação de botão: Neste ponto, você precisará definir o modelo. Adicione a seguinte marcação realçada. Este marcação especifica dois elementos Rectangle com bordas arredondadas, seguidos por um DockPanel. O DockPanel é usado para hospedar o ContentPresenter do botão. Um ContentPresenter exibe o conteúdo do botão. Nessa explicação 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. O código deve se parecer com o seguinte:
Adicione um glasseffect ao modelo: Em seguida, você adicionará o efeito de transparência. Primeiro crie alguns recursos que criam um efeito de gradiente de vidro. Adicione esses recursos de gradiente em qualquer lugar dentro do bloco Application.Resources:
<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 nós inserimos no Grid do 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 propriedade x:Name de "glassCube" é 0, para que quando você execute o exemplo você não veja o retângulo de vidro sobreposto na parte superior. Isso ocorre porque posteriormente adicionaremos triggers ao modelo para quando o usuário interage com o botão. No entanto, você pode ver a aparência do botão agora alterando o valor Opacity para 1 e executando o aplicativo. Consulte a figura a seguir. Antes de prosseguir para a próxima etapa, altere a Opacity de volta para 0.
Criar interatividade de botão
Nesta seção, você criará triggers de propriedades e triggers de evento para alterar valores de propriedade e executar animações em resposta às ações do usuário, como mover a 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 triggers dentro de seu modelo ou estilo. Para criar um Trigger, você define uma propriedade de "condição" sistema autônomo: O botão IsMouseOver valor da propriedade é igual a true. Em seguida, você define configuradores (ações) que ocorrem quando a condição do trigger é verdadeira.
Para criar interatividade de botão
Adicione modelo disparadores: Adicione marcação realçada para o 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 disparadores de propriedade: Adicione a marcação realçada para o ControlTemplate.Triggers bloco:
<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ê move o ponteiro do mouse sobre os botões.
Adicione um disparar de foco: Em seguida, adicionaremos alguma setters semelhantes para manipular o caso quando o botão tiver o foco (por exemplo, depois que o usuário clicar em).
<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 fica realçado após você ter clicado nele porque ele ainda tem o foco. Se você clicar em outro botão, o novo botão obtém foco enquanto o último o perde.
Add animations for MouseEnter and MouseLeave: Em seguida, adicionamos algumas animações para os disparadores. Adicione a seguinte marcação em qualquer lugar dentro do bloco ControlTemplate.Triggers.
<!-- 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 se reduz quando o ponteiro do mouse se move sobre o botão e retorna ao tamanho normal quando o ponteiro o deixa.
Há duas animações que são acionadas quando o ponteiro passa sobre o botão (evento MouseEnter é gerado). Essas animações reduzem o retângulo de vidro ao longo dos eixos X e Y. Observe as propriedades nos elementos DoubleAnimation — Duration e By. Duration especifica que a animação ocorre por meio segundo, e By especifica que o vidro se reduz por 10%.
O segundo trigger de evento (MouseLeave) simplesmente para o primeiro. Quando você para uma 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 à forma como era antes de o ponteiro do mouse ser movido sobre o botão. Para obter mais informações sobre animações, consulte Revisão de Animação.
Adicione uma animação para quando o botão for clicado: A etapa final é adicionar um disparar para quando o usuário clica no botão. Adicione a seguinte marcação em qualquer lugar dentro do bloco ControlTemplate.Triggers.
<!-- 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.
Resumo
Nessa explicação passo a passo, você executou os exercícios a seguir:
Controlou propriedades básicas dos botões no aplicativo inteiro usando um Style.
Criou recursos como gradientes a serem usados para valores de propriedades dos configuradores do Style.
Personalizou a aparência dos botões em todo o aplicativo aplicando um modelo aos botões.
Personalizou comportamento para os botões em resposta às ações do usuário (como MouseEnter, MouseLeave e Click) que incluiu efeitos de animação.
Consulte também
Tarefas
Demonstra Passo a passo: Create a Button by Using Microsoft Expression Blend