WPF - Exibindo e posicionando Imagens no Canvas


 Hoje veremos como podemos exibir imagens e a seguir posicioná-las usando os eventos do mouse no elemento de leiaute Canvas da WPF - Windows Presentantion Foundation .

Chegou o Curso ASP .NET MVC 5 Vídeo Aulas (C#)

Clique e Confira

Na WPF o layout é determinado pelo container que você usa e embora existem muitos containers a escolher, existem os seguintes princípios básicos:

O Windows Presentation Foundation (ou WPF), inicialmente chamado de Avalon, é um subsistema gráfico disponível a partir do .NET Framework 3.0(inicialmente chamado de WinFX), que usa uma linguagem de marcação, conhecida como XAML para desenvolvimento de Interfaces ricas. O WPF está incluído com o Windows Vista e Windows Server 2008, e também está disponível para Windows XP Service Pack 2 e mais recentes, e Windows Server 2003.

Este oferece um modelo consistente de programação para construir aplicações e uma clara separação entre interface com o usuário e lógica de negócios. Uma aplicação WPF pode ser implantada em ambiente Desktop ou hospedada em um site da web.

Se propõem a unificar um número de serviços de aplicações: interface com o usuário, desenhos 2D e 3D, documentos fixos e adaptáveis, tipografia avançada, gráficos vetoriais, gráficos Raster, animações, vinculação de dados, áudio e vídeo.

http://pt.wikipedia.org/wiki/Windows_Presentation_Foundation

Quase todos os elementos WPF com os quais trabalhamos derivam da classe base System.Windows.FrameworkElement e herdam algumas propriedades específicas de leiaute. Estas propriedades servem para refinar a maneira como os elementos são posicionados no seu controle pai. Dentre estas  propriedades básicas temos: Margin, VerticalAlignment e HorizonalAlignment.

Todos os containers de leiaute WPF são Panels que derivam da classe abstrata System.Windows.Controls.Panel conforme mostra a figura abaixo:

O Canvas é o elemento de leiaute mais básico no WPF sendo diferente de todos os demais Panels.

A diferença reside no fato de que o Canvas não adiciona nenhum comportamento de layout especial aos seus controles filhos. O canvas precisa ter um tamanho exato para Width e Height e todos os seus controles filhos precisam ter um tamanho e posição exatamente definidas.

Seus elementos filhos são posicionados em coordenadas explicitas. As coordenadas podem ser especificadas com relação a  um lado do panel usando as propriedades Canvas.Left, Canvas.Top, Canvas.Bottom and Canvas.Right.

O Canvas oferece suporte ao posicionamento absoluto e fornece a funcionalidade de layout menos interna para seus controles contidos; permite também controlar a posição contida em um deslocamento do qualquer canto do painel.

Este Panel é usado para agrupar elementos gráficos em 2D junto e não para elementos de interface de usuário.

Por exemplo, se um controle especifica valores para Top e Right, ele manterá uma distância constante do canto superior direito.Se forem especificados os valores para mais de uma propriedade horizontal ou vertical, em seguida, um dos valores será ignorado.

 

Neste artigo veremos como exibir imagens em um elemento Canvas e permitindo que o usuário posicione-as usando os eventos do mouse.
 

Recursos usados :

Criando o projeto no VS 2013

Abra o VS 2013 Express for Windows desktop e clique em New Project;

A seguir selecione Visual Basic -> WPF Application;

Informe o nome Canvas_Imagem e clique no botão OK;

Abra o arquivo MainWindow.xaml e inclua o código XAML abaixo onde definimos :

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Canvas - Imagens" Height="450" Width="625" Background="Aqua">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Canvas x:Name="canvas"
            MouseLeftButtonDown="CanvasMouseLeftButtonDown"
            MouseLeftButtonUp="CanvasMouseLeftButtonUp"
            MouseMove="CanvasMouseMove"/>
        <Button Grid.Row="1" Content="Adicionar uma Imagem" Click="btn_AdicionarImagem"/>
    </Grid>
</Window>

O leiaute gerado pelo código XAML pode ser visto abaixo:

No início do arquivo MainWindow.xaml.vb vamos definir duas variáveis, uma para tratar a imagem e outra para tratar a posição do  mouse:

Dim ImagemArrastada As Image
Dim posicaoMouse As
Point

Agora vamos definir no arquivo MainWindow.xaml.vb o evento Click - btnAdicionarImagem - o código que permite ao  usuário selecionar uma imagem exibindo no Canvas:

   Private Sub btn_AdicionarImagem(sender As Object, e As RoutedEventArgs)
        Try
            Dim ofd1 = New Microsoft.Win32.OpenFileDialog()
            'filtra as imagens
            ofd1.Filter = "Image Files (*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp"
            'se selecionou um arquivo então trata e exibe a imagem
            If CBool(ofd1.ShowDialog()) Then
                Dim bitmap = New BitmapImage(New Uri(ofd1.FileName))
                Dim imagem = New Image() With {.Source = bitmap}
                'ajusta a imagem
                canvas.SetLeft(imagem, 0)
                canvas.SetTop(imagem, 0)
                canvas.Children.Add(imagem)
            End If
        Catch ex As Exception
            MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButton.OK, MessageBoxImage.Error)
        End Try
    End Sub

Vamos definir agora o código para cada evento do mouse definido :

1- MouseLeftButtonDown

Private Sub CanvasMouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs)
        Try
            Dim imagem = TryCast(e.Source, Image)
            'se a imagem existe captura a posição do mouse
            If imagem IsNot Nothing AndAlso canvas.CaptureMouse() Then
                posicaoMouse = e.GetPosition(canvas)
                ImagemArrastada = imagem
                ' em caso de multiplas imagens
                Panel.SetZIndex(ImagemArrastada, 1)
            End If
        Catch ex As Exception
            Throw
        End Try
    End Sub
 

2- MouseLeftButtonUp

Private Sub CanvasMouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs)
        Try
            If ImagemArrastada IsNot Nothing Then
                canvas.ReleaseMouseCapture()
                Panel.SetZIndex(ImagemArrastada, 0)
                ImagemArrastada = Nothing
            End If
        Catch ex As Exception
            Throw
        End Try
    End Sub
 

3- MouseMove

 Private Sub CanvasMouseMove(sender As Object, e As MouseEventArgs)
        Try
            If ImagemArrastada IsNot Nothing Then
                Dim position = e.GetPosition(canvas)
                Dim offset = position - posicaoMouse
                posicaoMouse = position
                canvas.SetLeft(ImagemArrastada, canvas.GetLeft(ImagemArrastada) + offset.X)
                canvas.SetTop(ImagemArrastada, canvas.GetTop(ImagemArrastada) + offset.Y)
            End If
        Catch ex As Exception
            Throw
        End Try
    End Sub
 

Executando o projeto e selecionando uma imagem teremos :

Após isso podemos posicionar a imagem conforme mostra a figura a seguir:

Podemos também selecionar múltiplas imagens posicionando-as no elemento conforme figura abaixo:

Normalmente a Z-Order dos elementos no interior do elemento Canvas é especificada pela ordem no código XAML. Mas neste exemplo estamos sobrescrevendo a Z-Order e explicitamente definindo a propriedade  Panel.SetZIndex(ImagemArrastada, 1) para o elemento.

Pegue o projeto completo aqui:  Canvas_Imagem.zip

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti