Welcome to Linha de Código Sign in | Join | Help

Testando WebParts com o ASP.NET AJAX 1.0

Ontem fiquei fazendo alguns testes com webparts e Ajax e resolvi criar este resumo e compartilhar com vocês :

Posso usar webparts com ajax ?

Minha resposta SIM.

Para usar webparts com ajax  não preciso fazer nada ?

Minha resposta e não, você precisa fazer sim! Infelizmente nem todas as funcionalidades de webparts  foram implementadas , tanto é que ela não faz parte da versão RTM e sim da versão “Future” . Veja as limitações (sem fazer nada) em

http://forums.asp.net/thread/1545256.aspx 
ou em
http://blogs.msdn.com/mharder/archive/2007/01/23/webparts-and-asp-net-ajax-1-0.aspx

Então só posso Ajax com a versão “FUTURE” ?

Minha resposta e não, PODE IR ALEM, VOCE PODE USAR WEBPARTS COM A VERSÃO ASP.NET AJAX  1.0!!!!!!!!!!!!!!!!!.

E posso usar Ajax com Webparts em produção?

Minha resposta e não, mas por quê?  Por que embora as funcionalidades de Drag and Drop passem a funcionar com as soluções que demonstro mais abaixo, ainda precisa ser amadurecida e melhorada, inclusive se pensando em cross-browser. 

O Objetivo aqui  é compartilhar o conhecimento e mostrar que é possível fazer funcionar webparts com Ajax , quem acompanhou a evolução lembra que durante os ctps  a compatibilidade entres os browses veio depois , como em qualquer amadurecimento de código.

Mas como é possível? Já li que isso é mito uma lenda não é fato....

Minha resposta é que leia ate o final e depois tire a conclusão do que é lenda e que fato e pode ser feito, e conclua você mesmo, afinal não estou aqui para ficar demostrando o que não funciona e sim para compartilhar conhecimento  e aprender junto com a comunidade , ou seja com vocês.


Mas esta solução é sua?

Não. Estava trabalhando em uma solução para este cenário, porem meu trabalho foi abreviado por encontrar uma solução bem mais adiantada e seguindo o mesmo raciocínio que  o meu.

Mas afinal qual é a Mágica?

Bem antes de mostrar como é a mágica, vamos entender o que não funciona:

Uma das principais funcionalidades de usar webparts é você poder mover as webparts entre as webzones. Uma das coisas desagradáveis era que quando fazia isso para cada webparts que você movia era executado um postback e página era toda carregada.

Com a chegada do AJAX  isso pareceu ter sido resolvido de uma forma  muito elegante não ocorrendo mais o postback, tornando a usabilidade bastante atraente. Infelizmente  esta funcionalidade com o Ajax foi retirada nas versões betas e também  na versão RTM 1.0, sendo deixada para ser implementada em versões futuras.
Quando colocamos as webparts e o wepartmananger dentro do updatepanel o drag and drop  não funciona corretamente.  

Mas porque não funciona? 

É aqui que começa a mágica
.  Se observar o comportamento quando esta dentro do updatepanel ira perceber que funciona na primeira vez e depois quando é feito o “Partial render” pelo scriptmananger não é possível mais executar o drag and drop.  Este efeito indesejado esta centrado em um único componente: 

O webpartmananger.

O webpartmananger  que é responsável por gerar e registrar os scripts com as funcionalidades. Este script é que são os responsáveis pela funcionalidade Drag and drop, os Verbos dos menus e outras funcionalidades das webparzones.

Desta forma então será o webpartmananger que teremos que modificar para que o webparts funcione corretamente.

Mas porque precisamos modificar ele (webpartmananger) ? 

Porque quando colocamos ele dentro do updatepanel durante o primeiro render ele carrega os script  e executa as funcionalidades, mas depois do primeiro “Partial render” o Webpartmananger não consegue mas registrar os scripts e “se perde” criando exatamente  o comportamento  já descrito de apenas executar somente 1 vez, isso se explica porque o responsável por isso é o scriptmananger quando trabalhamos com  AJAX.
Simples não é..... São estes conceitos que ajudam a você a resolver cenários onde existe  pouca documentação e recursos existentes.

Vocês já leram  também pelo meu blog que os validators também  tem problemas quando usando dentro do updatepanel (principalmente dentro de templates de grids que estão dentro dos updatepanels) . A solução para os validtors foi mapear as classes responsáveis pelos controles para outra classe que resolver o problema.

A solução para webparts é feita da mesma forma! Justamente por este caminho que estava trabalhando quando me deparei com outra solução feita por outro desenvolvedor segundo exatamente esta linha!

Mas o que deve ser feito?

Primeiro criar  uma classe que herde do WebpartMananger e sobre-escrever o RenderClientScript (para se ter o controle do se se escreve na pagina). Com isso registramos os scripts pelo System.Web.UI.ScriptManager e não mais pelo System.Web.UI.ClientScriptManager

Esta simples mudança faz com que os script registrados sejam executados a cada refresh do updatepanel  que  é controlado pelo scriptmananger.

Estava bem próximo disso quando encontrei esta solução que estou descrevendo. 

Para completar a solução será necessário mapear as  classes do System.Web.UI.WebControls.WebParts.WebPartManager  para a classe que esta sendo criada da mesma forma que foi feita a solução para os validators.

<configuration>
    <system.web>
        <pages>
            <tagMapping>
            <add  
            tagType="System.Web.UI.WebControls.WebParts.WebPartManager"
            mappedTagType="Sample.Web.UI.WebParts.WebPartManager, Sample.Web.UI.WebParts"
            />
            </tagMapping>
        </pages>
</system.web>
</configuration>

E o código ? 
Vamos a explicação de algumas partes dele :

Como já falamos a classe herda de System.Web.UI.WebControls.WebParts.WebPartManager e o trecho abaixo mostra como esta sendo registrado o script necessário junto ao ScriptManager e depois durante a statup para garatir o resfresh do updatepanel.

Public Class WebPartManager
    Inherits System.Web.UI.WebControls.WebParts.WebPartManager

    Protected Overrides Sub RegisterClientScript()
        If Me.CheckRenderClientScript Then

            System.Web.UI.ScriptManager.RegisterClientScriptResource(Me,
            GetType(System.Web.UI.WebControls.WebParts.WebPartManager),
             "WebParts.js")

            System.Web.UI.ScriptManager.RegisterStartupScript(Me,
            Me.GetType, Me.ID & "_Script", Me.Script, True)

        End If
    End Sub

Abaixo parte de o script  necessário ser executado durante o startup.

    Private ReadOnly Property Script() As String
        Get
            Dim colorConverter As New System.Web.UI.WebControls.WebColorConverter
Dim _clientScript As String = String.Format("__wpm = new
 WebPartManager();{0}" & _
            "__wpm.overlayContainerElement =
 document.getElementById('{2}___Drag');{0}" & _
            "__wpm.personalizationScopeShared = {1};{0}" & _
"var zoneElement;{0}var zoneObject;{0}",
ControlChars.CrLf, Me.Personalization.CanEnterSharedScope.ToString.ToLower, Me.ClientID)
            For Each z As WebPartZone In Me.Zones……
            Return _clientScript
        End Get
    End Property

Você deve estar se perguntando como é possível saber que código escrever  para se chegar a este resultado ... Aqui Tb não existe nenhuma lenda nem nenhum “super guru” ..rs.rs, quem acompanha meu blog em  http://linhadecodigo.com.br/cs2/blogs/fcerqueira deve se lembra de uma dica que dei da nova versão do :

“Refletor 5.0 - Uma ferramenta indispensável” (http://linhadecodigo.com.br/cs2/blogs/fcerqueira/comments/588.aspx

No blog disse

“Embora muitos achem que a intenção é descompilar e ver o código fonte, estas ferramentas tem uma tarefa mais nobre :  Faciliar o entendimento do .NET framework.  Ajudar a melhorar a performance e reduzir os cast Uma grande fonte de aprendizado” 

E ai esta a outra parte da mágica, aprender  mais sobre o funcionamento vendo como é realizado as rotinas.

Uma pergunta final que pode ser feita : Esta solução é crossbrowser ?

Infelizmente não é, por enquanto esta solução esta compatível apenas com o Internet Explorer , porem mostra  que com um pouco de conhecimento pode-se se chegar a uma solução. O  legal de compartilhar conhecimento é poder mostrar os avanços, os caminhos . Compartilhando estes caminhos e códigos outros desenvolvedores aprendem melhor o funcionamento e pode evoluir a solução até chegar a uma maturidade de código que permita o uso em usa plenitude

Onde posso pegar todo o código fonte ?

Esta em um thread no fórum  www.asp.net  : http://forums.asp.net/thread/1621227.aspx 

Quem inica a thead e o propio autor da classe, a ele que devemos dar o grande parabens . De minha parte estou apenas ajudando a divulgar e compartilhar com vocês.

A todos um grande abraço

 

Published quarta-feira, 28 de março de 2007 12:20 by FCerqueira

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

What do you think?

(required) 
required 
(required)