Dev (Back & Front)ARTIGO

Mudando o background em um botão

Uma
questão presente nos Fóruns de Desenvolvimento do Windows
Phone foi sobre o XAML para exibir a imagem do background em um
botão quando este é pressionado. Gerar o XAML para fazer isso é bem fácil (se
você souber como!). Por mais que os pedidos sejam pelo XAML, eu acho de grande valor as instruções para criar o XAML para fazer isso.

Abra o Expression Blend e crie um novo projeto. Nele, adicione um
novo botão. Clique com o botão direito nele e selecione “Edit
template”->”Edit Copy”. Será pedido o nome do novo estilo do
botão que estamos criando (pode chamá-lo do que quiser), e o template será
definido no documento (página) ou globalmente para a aplicação. Se você somente
planeja usar o estilo em uma página, então você pode defini-lo dentro do
documento. Em geral, você provavelmente irá usar seu estilo em mais de uma página.
De qualquer maneira, para esse exercício, selecione a opção para criar o estilo
dentro do documento.

Mude para a visualização do código para que
possamos editar o XAML. No topo do seu documento, você verá um estilo definido
com o nome que você escolher. Procure em estilo até encontrar o construtor com um ContentControl dentro de um elemento Border. Ele irá se parecer com o seguinte.

<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" 
BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>

Iremos
fazer a maior parte das nossas mudanças nesse estágio. Precisamos colocar uma
imagem dentro desse elemento border. Ele ficará atrás do conteúdo e, portanto,
ela terá que aparecer antes do elemento ContentControl. O elemento Border
pode ter um filho, então precisamos transformar o filho direto do Border em um
Grid, e então inserir o elemento imagem e o elemento ContentControl dentro do
Grid. O atributo da imagem precisará de um nome e de ter sua Opacity em
zero, uma vez que a imagem normalmente não estará visível. O XAML resultante se
parecerá com o seguinte:

<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">								
<Grid>
<Image x:Name="BackgroundImage" Source="/Background.png"
Stretch="Fill" VerticalAlignment="Bottom" Opacity="0" />
<ContentControl x:Name="ContentContainer"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>

Quase
pronto! Temos apenas algumas coisas para fazer. Queremos que a imagem seja
visível quando o usuário estiver pressionando o botão. Procure no template e você encontrará vários elementos VisualStateGroup
definidos. Essa área contém as mudanças e as transições que precisam ocorrer no
botão quando certas coisas acontecem, como o botão sendo desabilitado, perdendo
ou ganhando foco, e assim por diante. Estamos interessados em mudanças que
ocorrem no estado em que ele está pressionado. Dentro do VisualState chamado
Press existe um StoryBoard contendo várias animações. Precisamos adicionar mais
uma animação que muda a opacidade do nosso botão. Como o último filho do
elemento StoryBoard, adicione o seguinte:

<DoubleAnimation To="100" Duration="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundImage" />

Agora,
se você executar o projeto, verá a imagem aparecer no botão toda vez que
você pressioná-lo, e desaparecerá quando você soltá-lo. Agora, como você usa
isso em outro projeto? Se você copiar o elemento Style desse projeto e
inseri-lo como um recurso dentro de outros projetos, ele estará pronto para ser
usado (apenas tenha certeza de que a fonte da sua imagem também apareça no seu
projeto alvo). O estilo pode ser aplicado a um botão ao configurar o buttons
style.

<Button  Style="{StaticResource MyCustomButton}"/>

Se
você quiser ver como todo o meu estilo ficou, aqui está.

<Style x:Key="MyCustomButton" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
<Setter Property="Padding" Value="10,3,10,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation To="100" Duration="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundImage" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">
<Grid>
<Image x:Name="BackgroundImage" Source="/Background.png" Stretch="Fill" VerticalAlignment="Bottom" Opacity="0" />
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>

</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

?

Texto original disponível em http://j2i.net/blogengine/post/2011/03/19/Changing-the-Background-on-a-Button.aspx

é engenheiro de software em Atlanta, Georgia (EUA), e trabalha como desenvolvedor há mais de 13 anos, atuando com tecnologias da Microsoft como Silverlight, ASP.Net e SQL Server.

Ver perfil

Mais de Joel Ivory Johnson