WPF – Criando Janelas Transparentes

São inúmeros os benefícios agregados ao WPF para os desenvolvedores que já possuem background em WindowsForms. Tenho explorado algumas dicas práticas e fáceis de implementar que ilustram alguns desses benefícios.  Quantas vezes, você – desenvolvedor WindowsForms – tentou criar formulários com formas geométricas diferentes das convencionais? Não é necessário responder. As alternativas que tínhamos, exigiam o uso de APIs Win32 para conseguirmos os resultados desejados.



Com WPF você pode criar facilmente formulários (janelas no WPF) das mais diversas formas. Por exemplo, você pode pegar uma imagem criada por um designer e utilizá-la como background da sua janela, acrescentar controles e funcionalidades como quaquer janela convencional.  


Veja abaixo um exemplo de janela transparente que apresenta a logomarca, criada por um designer profissional, para um software de gestão de bares e restaurantes que desenvolvi. Esta imagem é usada como splashscreen da aplicação. A Figura 1 apresenta a janela de splash em tempo de execução. A janela está limitada ao círculo da logomarca, o fundo azul é da minha Área de Trabalho.




Figura 1: Exemplo de Janela Transparente



Como não sou designer, e não me atrevo a desenhar nada, escolhi uma imagem com fundo transparente para ilustrar este artigo. Esta imagem apresenta alguns dados (daqueles de jogos), com aspecto de estarem em movimento e o fundo transparente. A imagem está no formato PNG. O objetivo aqui é demonstrar como você pode criar uma janela transparente de forma muito simples e prática. A Figura 2 apresenta nossa a janela transparente deste exemplo, em tempo de execução. Observe que o fundo preto pertence a Área de Trabalho, a janela está limitada a imagem dos dados e ao botão Fechar (imagem com X e fundo vermelho). O mais interessante neste recurso, é que você pode clicar entre os dados (na área transparente) e interagir com qualquer elemento que estiver atrás da janela, ou seja, sua janela assume a forma da imagem criada. Veja a Figura 3 onde há um ícone na Área de Trabalho que está selecionado entre os dados.




 Figura 2: A Janela Transparente em tempo de exeução




Figura 3: Ícone na Área de Trabalho selecionado através da janela transparente


Construindo o exemplo

Este artigo faz parte de uma série direcionada ao desenvolvedores iniciantes. O exemplo criado é simples e fácil de construir. Neste exercício de reproduzir o exemplo ilustrativo deste artigo, você aprenderá como criar uma janela transparente, como movimentar uma janela sem bordas utilizando o método Window.DragMove(), como utilizar os eventos Window.Closing e Window.KeyUp para interagir com sua aplicação. Para os absolutamente iniciantes, não só no WPF mas também na linguagem C#, no evento Window.Closing está um exemplo de aplicação da estrutura condicional switch com a enumeração MessageBoxResult. O template WPF Application foi utilizado para construir este exemplo. Veja a Janela Solution Explorer exibida na Figura 4.


Figura 4: A Janela Solution Explorer

A Janela Transparente MainWindow.xaml

São duas, as propriedades que devem ser ajustadas para esta tarefa. A propriedade AllowsTransparency deve ter valor True, e a propriedade Background deve ser definida como System.Windows.Media.ImageBrush. Você pode realizar esta tarefa utilizando a janela Properties Window, como mostra a Figura 5.


Figura 5: A janela Properties Window


Observe que a propriedade Background pode ser definida como uma cor sólida, gradiente ou uma imagem. Quando o desenvolvedor seleciona a opção imagem, a IDE do Visual Studio ainda permite que ele defina o comportamento da imagem ajustando as propriedades Stretch e Tile. Você ainda pode escolher uma imagem já incluída no projeto ou adicionar uma nova imagem a partir de uma pasta do FileSystem. Esses são apenas alguns dos recursos disponíveis na IDE o Visual Studio 2010. A propriedade WindowStyle também deve ser definida como True. Outra forma de ajustar estas propriedades é através do código XAML, como está demonstrado na Figura 6 a seguir.



 


Figura 6: O código XAML da janela MainWindow

A Imagem Transparente

Observe que não coloquei a imagem transparente (dados.png) como background da Janela, apenas defini que o background seria do tipo Image. E utilizei dois controles Image, um para a imagem de fundo (dados.png) e outro para o botão Fechar (X com fundo vermelho). Não coloquei a imagem dos dados diretamente no background da Janela para permitir o uso do método DragMove() de forma mais eficiente, associado ao evento MouseDown do controle Image. Poderia ter usado o evento MouseDown do container Grid, mas afetaria a resposta do evento Click da imagem usada como botão Fechar.

Codificando


As imagens a seguir apresentam o código C# necessário para implementar este exemplo. Observe atentamente os métodos, eventos, propriedades e objetos utilizados neste exemplo, você poderá utilizá-los em diversas situações.




  Figura 7: A sessão de declarações gerais




Figura 8: O código do controle Image usado como botão Fechar



Figura 9: O código do evento Window.KeyUp



Figura 10: O código associado ao evento Window.Closing



Figura 11: O método DragMove() associado ao evento MouseDown da imagem de fundo

 

Com isto, finalizamos nosso exemplo. Agora é só executar o aplicativo e observar o comportamento da janela transparente. Aprofunde seus conhecimentos sobre este tema visitando a comunidade WPF.

Faça download deste arquivo no formato PDF e também do código-fonte deste exemplo.


 

WPF – Botões com Imagens Alternadas para Ativado, Pressionado e Desativado

Um dos controles mais utilizados em todas as aplicações é o Botão (Button). E a cada novo projeto tentamos mudar sua aparência para melhorar a experiência visual do usuário e tornar nossa interface mais funcional. Uma prática muito comum é o uso de imagens nos botões, as imagens auxiliam o usuário a interpretar o comando associado ao botão. Nas aplicações WPF existem diferentes formas de implementar botões com imagens e comportamentos das mais diversas formas e variações. O propósito deste artigo é demonstrar como criar um botão com imagens que se alternam de acordo com o estado do botão (ativado, pressionado ou desativado). O exemplo que utilizei para ilustrar este artigo é simples e de fácil implementação. As imagens a seguir apresentam o botão em tempo de execução nos seus diferentes status.





Figura 1: O botão com imagem (ativado)



Figura 2: O botão com imagem (desativado)



 Figura 3: O botão com imagem (pressionado)


 


Construindo o exemplo


Utilizaremos dois projetos para ilustrar este exemplo. O primeiro projeto deve ser criado com o template WPF Application e será a aplicação de teste para o nosso botão com imagem. O segundo projeto deve ser criado com o template User Control Library, este projeto implementará nosso SampleImageButton. A Figura 4 mostra a janela Solution Explorer com a Solução de exemplo.



Figura 4: O projeto de exemplo


 


Criando o Botão de Exemplo


Adicione ao projeto User Control Library as imagens que você deseja usar no seu botão customizado. No meu caso eu coloquei três imagens de um cubo. O cubo cinza será exibido quando o botão estiver desabilitado, a imagem vermelha quando o botão estiver pressionado e o cubo amarelo quando o botão estiver em seu estado normal. O Quadro 1 apresenta o código XAML necessário para implementar a classe MyImageButton.


 


<!–As propriedades Width, Height, MaxHeight, MaxWidth, MinWidth podem ser usadas


para definir o tamanho padrão do controle. Assim quando o developer arrastar


o controle a partir da ToolBox, ele será criado com seu tamanho padrão–>


<Button x:Class=”ExemploWPFImageButton.MyImageButton” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”  


xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” Width=”120″ Height=”90″ MaxHeight=”90″ MaxWidth=”120″ MinHeight=”90″ MinWidth=”120″>


<Button.Template>


    <!–O ControlTemplate define o tipo de controle que será construido–>


    <ControlTemplate TargetType=”{x:Type Button}”>


        <!–Dois containers StackPanel e Grid acomodarão as imagens e o texto do botão–>


        <StackPanel Background=”#FF232222″ Width=”120″ Height=”90″>


            <Grid Margin=”0,10,0,0″>


                <!–As imagens que indicam os estados Pressionado e Desativado ficarão ocultas–>


                <!–A propriedade Visibility=”Hidden” se encarrega desta tarefa–>


                <Image Name=”Normal” Source=”Images/cubeYellow.png” Height=”48″ Width=”48″/>


                <Image Name=”Pressed” Source=”Images/cubeRed.png” Visibility=”Hidden” Height=”48″ Width=”48″/>


                <Image Name=”Disabled” Source=”Images/cubeGray.png” Visibility=”Hidden” Height=”48″ Width=”48″/>


            </Grid>


            <TextBlock TextAlignment=”Center” FontWeight=”Bold” Margin=”10″


                        Foreground=”WhiteSmoke”>Clique no Cubo</TextBlock>


        </StackPanel>


        <!–Aqui está o responsável pela troca de imagens de acordo com o estado do botão–>


        <!–Os Triggers podem ser usados para diversas aplicações, este é um bom exemplo–>


        <ControlTemplate.Triggers>


            <!–O primeiro Trigger avalia a propriedade IsPressed–>


            <Trigger Property=”IsPressed” Value=”True”>


                <!–O elemento Setter através do atributo TargetName estabelece o vínculo com a imagem–>


                <!–e o atributo Property indica a Propriedade, Value atribui o valor desejado–>


                <Setter TargetName=”Normal” Property=”Visibility” Value=”Hidden”/>


                <Setter TargetName=”Pressed” Property=”Visibility” Value=”Visible”/>


            </Trigger>


                <!–O mesmo conceito é aplicado para avaliar a propriedade IsEnabled–>


            <Trigger Property=”IsEnabled” Value=”False”>


                <Setter TargetName=”Normal” Property=”Visibility” Value=”Hidden”/>


                <Setter TargetName=”Disabled” Property=”Visibility” Value=”Visible”/>


            </Trigger>


        </ControlTemplate.Triggers>


    </ControlTemplate>


</Button.Template>


</Button>


Quadro 1: Código XAML do controle MyImageButton


 


O Quadro 2 apresenta o código do arquivo MyImageButton.cs.


 


using System.Windows.Controls;


 


namespace ExemploWPFImageButton


{


    /// <summary>


    /// Interaction logic for MyImageButton.xaml


    /// </summary>


    public partial class MyImageButton : Button


    {


        public MyImageButton()


        {


            InitializeComponent();


        }


    }


}


Quadro 2: Código do arquivo MyImageButton.cs


 


Por último, vamos adicionar o botão na Janela MainWindow do projeto de exemplo. Observe o código XAML no Quadro 3.


 


<Window x:Class=”ExemploWPFImageButton.MainWindow”


        xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”


        xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”


        Title=”DevBrasil | WPF | Image Button” Height=”319″ Width=”351″


        xmlns:my=”clr-namespace:ExemploWPFImageButton”


        xmlns:my1=”clr-namespace:ExemploWPFImageButton;assembly=SampleImageButton”>


<Grid Language=”pt-BR” Background=”#FF141212″>


        <Button Content=”Ativar/Desativar” Height=”30″ HorizontalAlignment=”Left” Margin=”103,198,0,0″ Name=”button1″ VerticalAlignment=”Top” Width=”120″ Click=”button1_Click” />


        <my1:MyImageButton Content=”Button” Height=”23″ HorizontalAlignment=”Left” Margin=”103,82,0,0″ Name=”myImageButton1″ VerticalAlignment=”Top” Width=”75″ />


    </Grid>


</Window>


Quadro 3: A janela MainWindow


 


 


Agora é só executar seu projeto de exemplo e observar o comportamento do botão em seus três estados diferentes. Existem diversas técnicas para criar controles customizados, este é um exemplo prático para customizar seus botões. Você pode empregar esta técnica para criar uma biblioteca de botões padronizados para sua aplicação.


 


Aprofunde seus conhecimentos sobre este tema visitando a comunidade WPF.


Faça download deste arquivo no formato PDF e também do código-fonte deste exemplo.


 


 


 

Como invocar o método SelectAll() para todos os controles TextBox numa aplicação WPF

Numa aplicação WindowsForms ou WPF uma prática muito comum é a utilização do método SelectAll() dos controles TextBox para selecionar o conteúdo digitado sempre que o controle recebe o foco. Este recurso é familiar para os usuários deste tipo de aplicação e agiliza a entrada de dados.



Você pode invocar o método SelectAll() a qualquer momento para selecionar o texto digitado no controle TextBox. Mas, uma forma prática para implementar este recurso é utilizar o evento OnStartup do objeto Application. Através deste evento você pode modificar o comportamento dos controles TextBox de forma que todos passem a disparar o método SelectAll() automaticamente, sempre que receberem o foco.



Esta abordagem não se limita aos controles TextBox, você pode utilizar a mesma técnica para customizar qualquer evento de qualquer controle utilizado na sua aplicação.



Exemplo prático


Para este exemplo, vamos criar um novo projeto com o template WPF Application. Eu chamei meu projeto de ExemploWPFTextBoxSelectAll. Na janela principal, MainWindow.xaml, adicione cinco controles TextBox. Defina o valor da propriedade Text com conteúdo aleatório, apenas para ilustrar o comportamento dos controles após nossa implementação. Sua janela MainWindow deverá apresentar aspecto semelhante ao da Figura 1.




Figura 1: A Janela MainWindow

Modificando o arquivo App.xaml.cs

Para esta abordagem, precisamos modificar o arquivo App.xaml.cs, acrescentando o código apresentado no Quadro1. O primeiro procedimento, protected override void OnStartup(StartupEventArgs e) substitui o evento original Application.OnStartup, registrando o novo conteúdo para o evento TextBox.GotFocusEvent.



Quadro 1: O arquivo App.xaml.cs

 

Testando a aplicação

Agora é só executar a aplicação e utilizar a tecla TAB para navegar através dos controles TextBox e observar que o método SelectAll() é executado selecionando o conteúdo dos controles. Outro exemplo no qual você pode aplicar esta mesma técnica é modificar o evento KeyDown dos controles TextBox para permitir que seu usuário navegue através dos controles, utilizando a tecla ENTER ao invés do TAB.

 

Aprofunde seus conhecimentos sobre este tema visitando a comunidade WPF.

 

Faça download deste arquivo no formato PDF e também do código-fonte deste exemplo.