Custom Loading no Silverlight

By rdorta at setembro 30, 2009 11:12
Filed Under: Silverlight

Olá amigos, já repararam que toda aplicação em Silverlight sempre tem o mesmo Loading? Esse loading vem do próprio Silverlight e por já existir dificilmente nós desenvolvedores mudamos essa animação.

Mas para os intrépidos designers que não se conformam com isso (inclusive o que trabalha comigo) segue abaixo a forma como você pode trocar seu loading e ainda por cima como você pode manipular objetos via Javascript, muito necessário quando você está utilizando Silverlight em páginas que não são criadas com .Net (aspx).

Abaixo segue o código HTML do Silverlight:

<script type="text/javascript" src="Splash/SplashScreen.js"></script> 
...
...
<object id="Xaml1" data="data:application/x-silverlight-2," 
type="application/x-silverlight-2" width="100%" height="100%"> ...
<param name="splashscreensource" value="Splash/SplashScreen.xaml"/>
<param name="onSourceDownloadProgressChanged" value="onSourceDownloadProgressChanged" />
 

Agora em sua aplicação crie uma página SplashScreen.XAML:

<StackPanel xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
VerticalAlignment="Center" Margin="0,100,0,0">
<Image Source="../Splash/slc-watermark.png"
Height="47" Width="343"
HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="10" />
<Grid HorizontalAlignment="Center">
<Rectangle x:Name="rectBorder" StrokeThickness="1" Stroke="#FFC8C8C8"
Height="7" Width="200" HorizontalAlignment="Left"/>
<Rectangle x:Name="rectBar" Fill="#FFC8C8C8"
Height="7" Width="0" HorizontalAlignment="Left" />
</Grid>
</StackPanel>

 

E por fim, segue o código javascript para movimentar a barra de loading:

function onSourceDownloadProgressChanged(sender, eventArgs) {
var myHost = document.getElementById("Xaml1");
var rectBar = myHost.content.findName("rectBar");
var rectBorder = myHost.content.findName("rectBorder");
if(eventArgs.progress)
rectBar.Width = eventArgs.progress * rectBorder.Width;
else
rectBar.Width = eventArgs.get_progress() * rectBorder.Width;
}

 

Me perdoem amigos desenvolvedores por dar armas ao seus designers e fazer com que eles atormentem a vida de vocês, mas uma aplicação Silverlight bem feita envolve sempre um bom designer :)

Até a próxima Arqinovação!!!

Padrões de Arquitetura para Silverlight – MVVM (Model – View - ModelView)

By rdorta at setembro 17, 2009 12:11
Filed Under: Silverlight, Arquitetura

Neste post vou falar um pouco sobre o padrão MVVM e como utiliza-lo com Silverlight.

MVVM? É de comer?

rs. Não, não é nenhum xingamento e muito menos algo de comer.

MVVM ou Model View – ModelView é um design pattern que na minha opinião é o melhor patter para se desenhar aplicações em Silverlight.

Porque não utilizar outros Patterns mais conhecidos como MVC ou MVP?

No padrão MVP, o Presenter é responsável pela configuração e gerenciamento de estado de uma determinada view.

No padrão MVP o Controller tem um papel  parecido com o do Presenter.

Porém em Silverlight, a nossa camada de VIEW ou exibição contém um XAML que pode conter diversos Bindings, triggers, e gerenciamentos de estado, diferente das Views dos outros Patterns que são “burras” no Silverlight o XAML tem inteligência e vida própria.

Qual a solução?

O MVVM é um padrão derivado do MVP e do MVC, que foi disceminado pela comunidade de desenvolvimento WPF da Microsoft. A grande diferença é que apesar da ViewModel manipular e definir estados da View, a View pode declarativamente realizar bindings para propriedades da ModelView.

Separando melhor as camadas:

View = Composição de XAML e C# que manipula estados do XAML.
Model = Como as Models de MVC e MVP, define as chamadas de regras de negócio para exibição
ModelView = Camada que prepara os dados recebidos da Model para exibição no XAML.

Abaixo segue um gráfico para ilustrar o que disse acima:

fig01.gif

Hands On Mode ON

Para ilustrar melhor ainda o processo, vamos criar um MVVM Hello World em Silverlight:

No Visual Studio 2008 crie um novo projeto e permita que ele crie o projeto de testes:

image

Na sua Page.XAML, copie o código abaixo:

<UserControl x:Class="ExemploMVVM.Page"
    xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid Background="White" ShowGridLines="True" x:Name="LayoutRoot">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock x:Name="txb1" Text="{Binding Nome}"></TextBlock>
        <TextBlock x:Name="txb2" Text="{Binding Idade}" Grid.Row="1" Grid.Column="0"></TextBlock>
        <TextBlock x:Name="txb3" Text="{Binding Sobrenome}" Grid.Row="0" Grid.Column="1"></TextBlock>
        <TextBlock x:Name="txb4" Text="{Binding Curso}" Grid.Row="1" Grid.Column="1"></TextBlock>
    </Grid>
</UserControl>

 

Agora vamos definir uma Classe do Tipo Aluno, para ser nosso objeto de transporte.

namespace ExemploMVVM
{
    public class Aluno
    {

        public Aluno(string pstrNome, string pstrSobrenome, int pintIdade, string pstrCurso)
        {
            this.Nome = pstrNome;
            this.Sobrenome = pstrSobrenome;
            this.Idade = pintIdade;
            this.Curso = pstrCurso;
        }

        private string gstrNome;
        private string gstrSobrenome;
        private int gintIdade;
        private string gstrCurso;

        public string Nome
        {
            get { return gstrNome; }
            set { gstrNome = value; }
        }
        public string Sobrenome
        {
            get { return gstrSobrenome; }
            set { gstrSobrenome = value; }
        }
        public int Idade
        {
            get { return gintIdade; }
            set { gintIdade = value; }
        }
        public string Curso
        {
            get { return gstrCurso; }
            set { gstrCurso = value; }
        }

    }
}

Agora vamos criar nossa View Model. Reparem que ela recebe uma interface IAlunoView e um Serviço para ser Rodado. Isso expande as possibilidade de utilização, sendo que você pode definir uma interface para serviços também, e dessa forma você pode popular n views com n serviços.

namespace ExemploMVVM
{
    public class AlunoViewModel
    {
        private IAlunoView view;  
        public string Nome{ get; set;}  
        public string Sobrenome{ get; set;}  
        public int Idade { get; set; }  
        public string Curso { get; set; }  
        private IAlunoService svcAluno;

        public AlunoViewModel(IAlunoView view, IAlunoService svcAluno)  
        {  
            this.view = view;
            this.svcAluno = svcAluno;  
            Initialize();   
        }  

        private void Initialize()  
        {
            var p = svcAluno.ObterAlunoCurso("Arquitetura");
            Nome = p.Nome;
            Sobrenome = p.Sobrenome;
            Idade = p.Idade;
            Curso = p.Curso;  
        }  

    }
}

E  por fim, o C# da nossa View:

namespace ExemploMVVM
{
    public partial class Page : UserControl, IAlunoView
    {

        private readonly AlunoViewModel vmm; 

        public Page()
        {
            InitializeComponent();
            vmm = new AlunoViewModel(this, new AlunoService());
            this.DataContext = vmm;  
        }
    }
}

Resumo da ópera

Resumindo, a grande vantagem de utilizar MVVM com Silverlight é que você pode aproveitar todo o poder de utlização de Bindings do XAML e ainda assim, criar um modelo de arquitetura onde você pode reutilizar a mesma regra de negócio(ViewModel e Model) com diversos designs diferentes(Views); No nosso caso, poderiamos tanto utilizar essa visualização dos quatro quadrados quanto fazer um CARD FLOW com os nomes e fotos dos alunos, quanto também criar uma visualização de grid com os dados dos alunos expostos.

Abaixo segue o código fonte que utilizei para esse exemplo.

ExemploMVVM.zip (782,28 kb) 

Abraços a todos e espero que possam usufluir desse modelo de arquitetura muito recomendado para aplicações em Silverlight.

Até a próxima Arqinovação!!!

 

Arquitetura de Aplicações Silverlight

By rdorta at setembro 17, 2009 11:05
Filed Under: Silverlight, Arquitetura

Ultimamente tenho visto diversas discussões sobre como criar aplicações Silverlight e como adequar essa tecnologias em algum design pattern comum no mercado como MVC, MVP, MVVM.

Vou tentar ilustrar nesse post como eu imagino uma aplicação Silverlight do ponto de vista de um arquiteto de software.

Web ou Client-side

Uma das coisas mais legais de Silverlight, é que apesar de ser uma tecnologia Web, ela roda em cima de um plugin que é instalado no computador do Cliente, portanto eu considero o paradigma de desenvolvimento Silverlight muito pais parecido com o desenvolvimento de aplicações Desktop do que com  o desenvolvimento de aplicações Web.

Sempre que criamos uma aplicação Silverlight no VS 2008 o próprio VS já se propõe a criar uma aplicação Web para que você possa testar sua aplicação.

Isso está mais do que correto, você pode estruturar seu desenvolvimento em dois lados:

image

Você deve sempre pensar que o seu Client de Silverlight é REALMENTE uma aplicação Client, portanto, você pode desenvolver utilizando qualquer pattern interessante ao momento, como Singleton, Abstract Factory e Observer(esse muito recomendado).

Já seu lado Server-Side, ou seja sua aplicação Web, você também pode estruturar utilizando as melhores práticas voltadas para web, como a criação de serviços ou handlers.

Nos meus próximos posts vou tentar abordar como utilizar as melhores práticas de arquitetura com o Silverlight e em quais cenários eles se aplicam.

Até a próxima Arqinovação!!!

Silverlight + Deep Zoom = RIA Experiences Parte 2 – Deep Zoom Dinamico – YES WE CAN

By rdorta at setembro 14, 2009 12:11
Filed Under: Silverlight

No meu post anterior, Silverlight + DeepZoom = RIA Experiences Parte 1 - Utilizando o Deep Zoom Composer, mostrei como podemos criar experiências simples com o Deep Zoom Composer.

Uma das grandes reclamações que eu costumo ouvir sobre o deep zoom é que não conseguimos criar experiências onde os dados sejam dinamicos, e a obrigatoriedade de utilizar o Deep Zoom Composer.

Esse meu post é dedicado a acabar com essa “crença”. Deep Zoom dinamico? YES WE CAN!!!

Criando o projeto

Para começar vamos precisar das seguintes ferramentas:

Siverlight 2 + Tools (também funciona com o 3, só estou usando o 2 porque estou finalizando um projeto que começou com ele)

Um pouco de conhecimento sobre imagens e tratamento de imagens com C# (google it!!!)

Deep Zoom Composer ( Leitor diz: nããããããõ!!!!…. Dorta diz: Calma!! é só pra pegar uma dll!!!!)

DeepZoomTools.dll

Bom, pra começar, vamos falar dessa dll. Você não vai achar praticamente nenhuma documentação sobre essa dll.

Ela foi criada pela própria equipe do Expression e foi divulgada nesse post do blog deles. Essa dll foi divulgada para que os desenvolvedores pudessem simular o funcionamento do Deep Zoom Composer em suas aplicações.

Abaixo segue os objetos que vamos utilizar e sua função:

ImageCreator: É o objeto de imagem utilizado pelo Deep Zoom.
CollectionCreator: Objeto responsável por criar aquelas diversas imagens para cada nível de zoom do nosso Deep Zoom

O que eu preciso saber de Deep Zoom?

Você deve ter conhecimento de como o Deep Zoom Composer trabalha, sugiro seguir meu post anterior Silverlight + DeepZoom = RIA Experiences Parte 1 - Utilizando o Deep Zoom Composer e criar algumas aplicações estáticas para entender alguns conceitos como:

Ao criar uma composição de Deep Zoom, são gerados inúmeros arquivos, com imagens e xmls que definem o comportamento de zoom da composição. (Pasta GeneratedImages)

Os xmls que são gerados definem os caminhos das imagens que serão utilizadas a cada nível de zoom

Vamos ao que interessa.

Crie um projeto do tipo Silverlight Application no VS 2008 e Peça para que seja criada uma aplicação WEB de testes. (Arquitetura em Siverlight vai dar um excelente post em breve).

image

Adiciona a sua pasta ClientBin do projeto WEB uma pasta chamada Generated Images

Adicione ao seu projeto WEB uma referencia a dll do DeepZoomTools : [Program Files]\Microsoft Expression\Deep Zoom Composer\DeepZoomTools.dll

O serviço que cria as imagens e xmls

Adicione ao seu projeto web, na pasta ClientBin, um Generic Handler, vamos chama-lo de ImageHandler:

image

 

Nosso serviço, vai ler as imagens de uma pasta (poderia ler qualquer imagem) e utiliza-las para montar um composição deep zoom.

O código que utilizei para buscar as imagens é bem simples:

private static List<string> ObterImagensDiretorio(DirectoryInfo pdiInformacaoDiretorio)
        {
            List<string> lstImagens = new List<string>();
            foreach (var finInformacaoImagem in pdiInformacaoDiretorio.GetFiles("*.jpg"))
            {
                lstImagens.Add(finInformacaoImagem.FullName);
            }
            return lstImagens;
        }

Agora no método ProcessRequest do nosso serviço, vamos inicializar as nossas variáveis:

1)Caminho para onde serão enviadas as imagens e XMLs

string strCaminhoImagensGeradas = context.Server.MapPath("~/ClientBin/GeneratedImages/");

2) Imagens que serão utilizadas no DeepZoom

           List<string> lstImagens = ObterImagensDiretorio(new DirectoryInfo(context.Server.MapPath("~/Imagem/")));

3) Lista de XMLs que serão gerados

          List<string> lstXMLs = new List<string>();

Por fim, mas não menos importante, criamos os objetos de imagem do Deep Zoom e a coleção:

O objeto ImageCreator e o objeto CollectionCreator possuem propriedades muito parecidas entre as quais podemos destacar:

TileSize – O tamanho que cada “tira” da composição deve assumir
TileFormat – O formato de arquivo de  cada “tira” (PNG, JPG, etc…)
ImageQuality – Como qualquer bom editor de imagem, você pode editar qual a qualidade de exportação da imagem, sendo 1 = 100%.

Ambos os objetos também possuem o método create:

ImageCreator.Create([Caminho original da imagem], [Caminho onde a imagem deve ser criada]);  - Cria as imagens e xmls referentes as imagens
ColectionCreator.Create([Lista dos caminhos dos xmls que contém as informações das imagens], [Caminho onde ele deve gerar a coleção completa]); Cria a estrutura completa de XML e imagens da composição

Segue o código abaixo:

foreach (string strImagem in lstImagens)
            {

                ImageCreator ic = new ImageCreator();

                ic.TileSize = 256;

                ic.TileFormat = ImageFormat.Jpg;

                ic.ImageQuality = 1;

                string target = strCaminhoImagensGeradas + "output_images\\" + Path.GetFileNameWithoutExtension(strImagem);

                ic.Create(strImagem, target);

                lstXMLs.Add(Path.ChangeExtension(target, ".xml"));

            }

            cc.TileSize = 256;

            cc.TileFormat = ImageFormat.Jpg;

            cc.MaxLevel = 8;

            cc.ImageQuality = 1;

            cc.Create(lstXMLs, strCaminhoImagensGeradas + "output");

WELL DONE!!! NOSSO SERVIÇO ESTA PRONTO!!! Agora vamos ao Silverlight:

DE VOLTA AO SILVERLIGHT

Agora vamos criar o DeepZoom utilizando o MultiScaleImage, no Silverlight.

Dentro dos seu LayoutRoot na sua Page.xaml crie os seguintes componentes:

<MultiScaleImage x:Name="msi" Height="Auto" Width="589"/>
        <Button Content="Embaralhar" HorizontalAlignment="Center" VerticalAlignment="Top" Click="Button_Click"/>

E agora no código Page.xaml.cs no método construtor, vamos invocar nosso serviço de geração de imagens:

WebClient wbc = new WebClient();
            wbc.OpenReadAsync(new Uri(“
http://localhost:3585/ClientBin/ImageHandler.ashx”));
            wbc.OpenReadCompleted += new OpenReadCompletedEventHandler(wbc_OpenReadCompleted);

E ao terminar o serviço vamos popular o nosso MultiScaleImage:

this.msi.Source = new DeepZoomImageTileSource(new Uri("http://localhost:3585/ClientBin/GeneratedImages/output.xml"));

DONE!!!

Espero que essas dicas ajudem a iluminar os passos para nova experiências com Silverlight e Deep Zoom.

Aqui está o link para o código fonte com imagens, um evento para capturar Mouse Wheel muito bom e um efeito de embaralhamento randomico nota 100000:

DeepZoomDinamico.zip (13,36 mb)

Nos vemos na próxima Arqinovação!!!

Silverlight + DeepZoom = RIA Experiences Parte 1 - Utilizando o Deep Zoom Composer

By rdorta at setembro 01, 2009 01:06
Filed Under: Silverlight

Estreando o novo blog, vou mostrar como criar experiências de Silverlight e DeepZoom para suas aplicações.

Introdução ao DeepZoom

O Deep Zoom é uma ferramenta poderosa que foi introduzida com o Silverlight 2. Com essa ferramenta é possível criar contextos de visualização de imagem muito interessantes.

Abaixo segue o link de um exemplo muito legal de aplicação criada utilizando Deep Zoom.

http://www.autotrader.co.nz/New/Search#keywords=&categories=Coupe 

Acredito que o Deep Zoom pode trazer uma grande vantagem em aplicações de E-commerce, fazendo com que possamos trazer uma experiência diversificada aos usuários de nossas aplicações, trazendo como benefícios uma nova forma de navegar por entre os produtos, sem necessitar de paginação e mostrando inicialmente para o cliente apenas informações que realmente interessam aos clientes.

 

Utilizando o Deep Zoom Composer

 

Para criar esta aplicação estou utilizando as seguintes ferramentas:

 

Visual Studio 2008

Silverlight 3
Silverlight Toolkit 3

Deep Zoom Composer

 

Como primeira parte dentre dois posts, vou mostrar como criar uma aplicação Silverlight com DeepZoom utilizando o Deep Zoom Composer.

 

Após a instalação do Deep Zoom Composer, você o encontra no seu Menu Iniciar -> Programas -> Microsoft Expression -> Deep Zoom Composer

Após a abertura do programa, vamos criar um novo projeto e denominá-lo de TesteDeepZoom.

A tela inicial do Deep Zoom Composer mostra o primeiro de três passos que é a escolha das imagens. Clique no botão Add Image no canto superior direito e adicione quantas imagens quiser.

No meu caso, adicionei 3 imagens de exemplo do Windows 7, note que as imagens aparecem na lista ao seu lado direito, e uma pré-visualização é exibida no painel principal.

 

Após estar satifisteito com as imagens que vai utilizar, clique no segundo passo que é a composição das imagens

Nesta tela, você tem diversos componentes que estão descritos no diagrama abaixo. Você pode arrastar as imagens da parte inferior da tela e adiciona-las a composição. Logo após basta redimensionar as imagens e posicioná-las de acordo com seu gosto. Note que você tem a barra de visualização no canto inferior esquerdo que é muito útil quando você estiver criando uma composição com muitas imagens. 

Legenda:
1) Definição de camadas da composição
2) Painel de Visualização Geral
3) Área de escolha de imagens

 Agora, vamos exortar o nosso projeto para uma aplicação Silverlight:

Nesta tela, você verá imediatamente um preview de como ficará nossa composição. Temos diversas formas de exportação.

Clique na aba Custom no canto direito.

Você verá no painel Output Types as opções:
1) Images (Exportas as imagens da composição)
2) Silverligh Deep Zoom (Projeto de Silverlight com o Deep Zoom aplicado em Multi Scale Image) Vou abordar esse assunto mais profundamente em outro post
3) Seadragon Ajax (Outra solução muito interessante que pretendo abordar em outro post mais pra frente)

Escolha a opção Silverligh Deep Zoom. Coloque um nome para a aplicação. Ex.: TesteDeepZoom
Escolha aond eo projeto será criado

No painel abaixo mantenha as configurações padrões e troque apenas o Template para Deep Zoom Classic + Source (pretendo criar um post avançado sobre o DeepZoomComposer também, onde irei abordar mais funcionalidades da ferramenta)

Clique em exportar, aguarde a exportação e você verá a janela abaixo com as opções de Ver no Broeser, abrir a pasta do projeto,  abrir a pasta com as imagens geradas pelo Composer.

Clique em abrir a pasta do projeto e você verá a solução de Visual Studio criada e pode reaproveitar os controles e códigos criados em sua aplicação Silverlight.

Sua primeira aplicação Deep Zoom está pronta!!!

Agora é a parte em que o desenvolvedor me pergunta:

"Legal! Mas como eu faço isso dinamicamente com as imagens da minha base relacionadas com meus produtos???"

Isso meus amigos... é assunto para meu próximo post, onde mostrarei como criar uma aplicação Deep Zoom dinamicamente com C# e base de dados.

Espero que o post seja útil para que você comece a ver como funciona o Deep Zoom e comece a enxergar novas maneira de criar suas aplicações.

Até a próxima Arqinovação!!!

Sobre mim

Ricardo Dorta

Ricardo Dorta

Arquiteto de sistemas da Makesys, atua na área de desenvolvimento de aplicações .NET há 5 anos.
MCP, MCAD e MCSD.