Capítulo 5: Input Validation and Site Navigation Lição 3: Using Web Parts
Autor: quintelab | Publicado: 2011-11-28T14:53:00-08:00

Muitos sites hoje possuem uma coleção de componentes que funcionam sozinhos e são auto-suficientes. Por exemplo, é padrão os sites serem divididos por uma barra lateral de navegação, uma barra no topo com o título, uma barra de rodapé, e uma área com notícias. Além disso muitos portais fornecem hoje componentes e relatórios como exemplo sobre o clima ou cotações financeiras.

ASP.NET Web Parts permite ao desenvolvedor criar estes controles. Com estes controles o usuário do site pode escolher se quer visualizar um relatório na tela, ou tem a opção de remover este controle e adicionar outro de informação do clima. Você pode fornecer ao usuário do site uma coleção de controles, para ele definir qual informação ele quer exibir na página que ele esta visualizando.

What Are Web Parts?

Web Part são componentes pré-definidos com funcionalidades que podem ser adicionados no site. Eles possuem uma estrutura definida, gerenciável e um modelo customizado. Alguns desses componentes podem ser movidos dentro do site para ser posicionado conforme a necessidade do usuário. A figura abaixo mostra um controle Web Part sendo posicionado pelo usário.

&nbsp;
Você pode utilizar o controle CatalogZone para adicionar um catalogo de controles em sua página, onde o usuário pode adicionar e/ou remover controles Web Part das regiões pré-definidas. A figura abaixo exibe este cenário onde o usuário visualiza uma lista de controles que ele pode adicionar ou remover de sua página.

Páginas de Web Part podem oferecer ao usuário diversas opções de personalização, isso é ótimo quando você desenvolve funcionalidades que abrangem um público amplo. Veja alguns Web Parts comuns que você pode criar:
Uma lista de artigos e notícias
Um calendário com os eventos
Uma lista de WebSites
Uma caixa de pesquisa
Controles de Navegação
Blog
Leitores de RSS, etc...
Qualquer controle seja padrão ou controle personalizado pode se tornar um Web Part, e não necessariamente terá que escrever diversas linhas de código, pois o Visual Studio auxilia nesta tarefa.

The WebParts Namespace

O Asp.Net possui vários Web Parts, são 13 os controles disponíveis na ToolBox do Visual Studio. Esses controles e classes podem ser encontrados dentro da Namespace System.Web.UI.WebControls.WebParts. Algumas dessas classes serão discutidas mais profundamente em lições posteriores. A lista a seguir contém as classes mais importantes:
WebPartManager: O controle WebPartManager é necessário em todas as páginas que inclui Web Parts. Ele não tem uma representação visual. Em vez disso, ele gerencia todos os controles de Web Parts e seus eventos na página especificada.
CatalogPart: O controle CatalogPart fornece a interface de usuário&nbsp;para gerenciar um grupo de Web Parts que podem ser adicionados a uma página de Web Parts. Este grupo é normalmente todo o site (e não apenas específicos para uma determinada página).
PageCatalogPart: O controle PageCatalogPart é semelhante ao controle CatalogPart. No entanto PageCatalogPart são apenas grupos dentro de uma página. Se um usuário fechar uma Web Parte ele pode utilizar o PageCatalogPart para adicionar a Web Parte novamente a página.
EditorPart: O controle EditorPart permite aos usuários definir personalizações, como a modificação de propriedades de uma Web Part especifica. 
DeclarativeCatalogPart: Este controle permite você declarar quais controles Web Parte estão disponíveis para adicionar no site.
WebPartZone: Controle utilizado para definir regiões que os controles Web Part podem ser hospedados.
EditorZone: Controle que definir a região na página onde pode existir os controles EditorPart.
CatalogZone: Defini uma região onde pode existir um controle CatalogPart.
Defining Web Part Zones

Você adiciona Web Parts na página colocando-as em zonas. As Zonas definem a área na página onde o usuário ou o desenvolvedor podem adicionar Web Parts. As zonas possuem as propriedades width, height e um local na página. É possível adicionar uma, nenhuma ou várias Web Parts dentro de uma zona. Veja a figura abaixo:


As zonas permitem definir estilos que serão aplicados a todos Web Parts que estiverem dentro dela. Isto é chamado de Web Part’s chrome. O chrome (cromo) inclui estilos de cabeçalho, estilos de menu, definições de borda e outros. As Web Parts que existiverem dentro de uma zona que teve seu chrome definido irá receber os mesmos estilos.

Você cria zonas de Web Parts com o controle WebPartZone. Este controle define a área onde podem ficar Web Parts, este controle também possui a propriedade HeaderText. Nesta propriedade irá o texto que será exibido ao usuário quando a página e a zona estiverem em modo de edição.

Para definir uma zona, você deve adicionar o controle WebPartZone em sua página, para adicionar controles a esta zona, primeiramente você deve adicionar o controle ZoneTemplate dentro de sua WebPartZone, e dentro deo ZoneTemplate você adiciona os demais controles e combinações de sua Web Part. Veja o código:

&lt;asp:WebPartManager ID="WebPartManager1" runat="server"&gt;
&lt;/asp:WebPartManager&gt;

&lt;asp:WebPartZone ID="WebPartZoneVendor" runat="server" HeaderText="Vendor Aggregate" style="width: 650px; height: auto"&gt;
&nbsp; &lt;ZoneTemplate&gt;

&nbsp;&nbsp;&nbsp; &lt;!--Add content to the zone--&gt;

&nbsp; &lt;/ZoneTemplate&gt;
&lt;/asp:WebPartZone&gt;

Note nas primeiras linhas desse código a existência do controle WebPartManager, apesar dele não ter uma representação visual para o usuário ele é obrigatório no uso de Web Parts.

Creating Web Parts

Existem três principais métodos de criar ASP.Net Web Parts. O primeiro é criar um user control padrão. O segundo é utilizar um controle ASP.Net como uma Label e definir como sua Web Part. O terceiro é criar um controle customizado que herde da classe WebPart, este terceiro será explicado no capítulo 7 "Creating Custom Web Controls", ele é o método mais demora e mais complicado. Os outros dois métodos são mais simples.

Building Web Parts with User Controls

Para criar uma Web Part baseado em um User Control, basta adicionar o User Controle dentro de uma Web Part Zone que o Asp.Net cuida do restante. Como qualquer User Control basta declara-lo em sua página usando a diretiva @ Register, como a seguir:

&lt;%@ Register src="VendorWebPart.ascx" tagname="VendorWebPart" tagprefix="uc1" %&gt;

Após seu User Controle estar registrado basta adicona-lo a uma Web Part Zone, dentro da declaração ZoneTemplate. Veja abaixo:


&lt;asp:WebPartZone ID="WebPartZone2" runat="server" HeaderText="Fabrikam" style="width: 350px; float: left; height: auto;"&gt;

&nbsp; &lt;ZoneTemplate&gt;
&nbsp;&nbsp;&nbsp; &lt;uc1:VendorWebPart ID="VendorWebPart1" runat="server" title="Fabrikam" /&gt;
&nbsp; &lt;/ZoneTemplate&gt;

&lt;/asp:WebPartZone&gt;

Creating a Web Part Control from an Existing ASP.NET Control

Seguindo o modelo de utilizar User Controls, é possível utilizar controles padrões do Asp.Net, basta adiciona-los dentro do elemento ZoneTemplate como foi feito acima. Veja o código abaixo:

&lt;asp:WebPartZone ID="WebPartZone1" runat="server" HeaderText="Vendor Aggregate" style="width: 700px; height: auto"&gt;
&nbsp; &lt;ZoneTemplate&gt;
&nbsp;&nbsp;&nbsp; &lt;asp:Label ID="Label3" runat="server" Text="" title="Vendor Totals"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div style="margin-top: 12px; margin-bottom: 20px; line-height: 30px; font-size: 12pt"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Active Users: &lt;a href="#"&gt;21&lt;/a&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;br /&gt;Total transactions today: &lt;a href="#"&gt;166&lt;/a&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;br /&gt;Revenue trades to-date: &lt;a href="#"&gt;$34,450&lt;/a&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/div&gt;
&nbsp;&nbsp;&nbsp; &lt;/asp:Label&gt;
&nbsp; &lt;/ZoneTemplate&gt;
&lt;/asp:WebPartZone&gt;

Enabling Users to Arrange and Edit Web Parts

Web Parts podem ser exibidas de diferentes formas. O modo como ela é exibida é indiferente do que o usuário esta fazendo com a Web Parts ou onde ela esta hospedada naquele momento. É possível alterar o modo de exibição das Web Parts utilizando o controle WebPartManager. Basta definir a propriedade DisplayMode, as opções disponíveis para esta propriedade são:
BrowseDisplayMode: É a forma padrão que os usuários navegam;
DesignDisplayMode: É o modo que permite aos usuários arrastar a Web Part para diferentes locais;
EditDisplayMode: Parecido com o DesignDisplayMode, permite aos usuários arrastar a Web Part, e além disso permite também editar os dados como título, tamanho, direção, aparência da janela e zona, utilizando os controles AppearanceEditorPart e LayoutEditorPart. Para utilizar este modo é necessário adicionar o controle EditorZone a sua página e em seguida o controle AppearanceEditorPart e/ou LayoutEditorPart;
CatalogDisplayMode:&nbsp; Permite ao usuário adicionar Web Parts que você especificou no controle CatalogZone. Para utilizar este modo é necessário ter o controle CatalogZone em sua página;
ConnectDisplayMode: Permite ao usuário estabelecer conexões manualmente entre os controles usando o controle ConnectionZone. Por exemplo uma Web Part pode ser ligada para mostrar informações de resumo e detalhe de um relatório. Para utilizar este modo é necessário ter o controle ConnectionZone em sua página.
O código a seguir exibe no clique de um botão como alterar o modo de exibição de uma Web Part:

protected void ButtonEdit_Click(object sender, EventArgs e)
{
&nbsp; string mode = (string)ViewState["mode"];
&nbsp; //switch modes
&nbsp; if (mode == "browse")
&nbsp; {
&nbsp;&nbsp;&nbsp; ViewState["mode"] = "edit";
&nbsp;&nbsp;&nbsp; ButtonEdit.Text = "Done";
&nbsp;&nbsp;&nbsp; WebPartManager1.DisplayMode = WebPartManager1.SupportedDisplayModes["Catalog"];
&nbsp; }
&nbsp; else
&nbsp; {
&nbsp;&nbsp;&nbsp; ViewState["mode"] = "browse";
&nbsp;&nbsp;&nbsp; ButtonEdit.Text = "Edit";
&nbsp;&nbsp;&nbsp; WebPartManager1.DisplayMode = WebPartManager1.SupportedDisplayModes["Browse"];
&nbsp; }
}

Repare que é usado a coleção SupportedDisplayModes para definir qual modo será exibido. Neste código vale explicar que o valor da ViewState foi salvo no evento PageLoad.

Connecting Web Parts

Uma possibilidade poderosa da Web Part é a conexão entre Web Parts. Para entender o uso, imagine o cenário onde esta desenvolvendo uma aplicação para controle da folha de pagamento dos funcionários, onde você tem:
A Web Part principal onde o usuário navega entre os funcionários.
Uma Web Part que exibe um gráfico das horas extras pagas ao funcionário.
Uma Web Part que exibe um gráfico de pizza que exibe o valor da folha de pagamento, benefícios e pensões que se encaixam no perfil global do funcionário.
E uma Web Part que compara o salário do funcionário com outros funcionários do mesmo cargo.
Com a conexão de todas Web Parts o usuário irá selecionar o funcionário uma única vez e todas as outras Web Parts irão ter suas informações atualizadas automaticamente.

Outro cenário é o desenvolvimento de um portal onde você tem várias Web Parts com informações distintas como clima, notícias locais e localização de bares. Porém todas elas necessitam do CEP para localizar essas informações, o usuário do portal irá informar o CEP uma única vez e todas as Web Parts irão se comunicar para ter acesso a este CEP.

Creating a Static Connection

Conexões podem ser estáticas ou dinâmicas. Se a conexão for estática, estabelecidade pelo desenvolver no momento de desenvolvimento ela não poderá ser alterada ou excluida pelo usuário. Conexões estáticas envolvem um Provider e um ou mais WebParts consumidores. Veja os passos para se criar os controles, tanto o provider como o consumidor e estabelecer uma conexão entre eles.

Primeiro Passo: Criar o WebParte provider.
O WebPart provider pode derivar da classe WebPart ou ser um user control. Você deve criar no seu WebPart um método público que tenha o atributo ConnectionProvider. Este método deve retornar o valor que o WebPart consumidor irá receber. Veja o código:

public partial class Provider : System.Web.UI.UserControl
{
&nbsp; string _textBoxValue = "";
&nbsp;&nbsp;
&nbsp; [ConnectionProvider("TextBox provider", "GetTextBoxValue")]
&nbsp; string GetTextBoxValue()
&nbsp; {
&nbsp;&nbsp;&nbsp; return _textBoxValue;
&nbsp; }
&nbsp;
&nbsp; protected void Button1_Click(object sender, EventArgs e)
&nbsp; {
&nbsp;&nbsp;&nbsp; _textBoxValue = TextBoxProvider.Text;
&nbsp; }
} 

Passo 2: Criar o WebPart consumidor.
Assim como o provider pode herdar de WebPart ou ser um user control. É necessário criar um método público que possua o atributo ConnectionConsumer que recebe o mesmo tipo que o método do ConnectionProvider retorna. Veja o código:

public partial class Consumer : System.Web.UI.UserControl
{
&nbsp; [ConnectionConsumer("TextBox consumer", "ShowTextBoxValue")]
&nbsp; void ShowTextBoxValue(string textBoxValue)
&nbsp; {
&nbsp;&nbsp;&nbsp; LabelConsumer.Text = textBoxValue;
&nbsp; }
}

Passo 3: Crie uma WebPage e adicione o controle WebPartManager, em seguida adicione o container WebPartZone.

Passo 4: Adicione seus WebPart ao WebPartZone, tanto o provider como o consumidor:

&lt;asp:WebPartZone ID="WebPartZoneProvider" runat="server" Height="400px" Width="300px"&gt;
&nbsp; &lt;ZoneTemplate&gt;
&nbsp;&nbsp;&nbsp; &lt;uc1:Provider ID="Provider1" runat="server" title="Provider" /&gt;
&nbsp;&nbsp;&nbsp; &lt;uc2:Consumer ID="Consumer1" runat="server" title="Consumer" /&gt;
&nbsp; &lt;/ZoneTemplate&gt;
&lt;/asp:WebPartZone&gt;

O próximo passo é estabelecer a conexão entre os dois controles. Adicione o elemento &lt;StaticConnections&gt; ao WebPartManager e dentro deste elemento adicione o controle WebPartConnection para declarar sua conexão.

O controle WebPartConnection deve ter a propriedade ID, a propriedade ProviderID identifica o controle provider, ProviderConnectionPointID identifica o método do provider, ConsumerID identifica o controle consumidor, ConsumerConnectionPointID identifica o método no consumidor. Veja o código:

&lt;asp:WebPartManager ID="WebPartManager1" runat="server"&gt;
&nbsp; &lt;StaticConnections&gt;
&nbsp;&nbsp;&nbsp; &lt;asp:webPartConnection
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ID="conn1"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ProviderID="Provider1"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ProviderConnectionPointID="GetTextBoxValue"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConsumerID="Consumer1"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConsumerConnectionPointID="ShowTextBoxValue" /&gt;
&nbsp; &lt;/StaticConnections&gt;
&lt;/asp:WebPartManager&gt;

Repare que você deve criar um controle WebPartConnection para cada par de controle conectado.

Enabling Dynamic Connections

Conexões dinâmicas podem ser estabelecidades pelo usuário. Para permitir esta ação você precisa adicionar o controle ConnectionsZone em sua página. 
Para permitir que os usuários criem ou parem conexões, siga os seguintes passos:
Crie uma página com um provider e um consumidor como explicado anteriormente.
Opcionalmente, estabeleça uma conexão estática entre o provider e o consumidor. Esta será uma conexão padrão que estará sempre disponível para o usuário, mas ele pode modificar criar ou parar outras conexões dinâmicas.
Adicione o controle ConnectionsZone em sua página.
Adiciona o controle para permitir que o usuário entre no Modo Connect como explicado anteriormente em "“Enabling Users to Arrange and Edit Web Parts".
Establishing Dynamic Connections Among Web Parts

Quando um usuário acessar sua página ele pode alterar para o modo de conexão e utilizar o controle ConnectionsZone para editar as conexões. Veja os passsos:
Altere o modo de visualização para connect.
O menu do WebPart irá aparecer entre o provider e consumidor, clique em Connect no menu, veja a imagem: 
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. Irá aparecer o objeto ConnectionsZone:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.Caso já exista uma conexão, clique em Disconnect para fechar esta conexão. Em seguida clique em Create A Connection To A Consumer, selecione o consumidor e clique em Connect:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.Quando finalizar a edição das conexões clique em Close. As WebParts estarão conectadas como se fosse feito estaticamente.
Personalizing Web Parts
WebParts suportam personalização. A personalização permite que as alterações feitas sejam armazenadas por cada usuário, permitindo que ele visualize a página da mesma forma na próxima visita. Personalização de WebParts dependem dos cookies do navegador do usuário, através das informações dos cookies, serão buscadas as personalizaçãoes feitas no banco de dados. Armazenada essas informações por usuário, normalmente você vai querer utilizar autenticação, mas isso não é necessário.
Enabling Personalization for Custom Controls
Para permitir esta personalização nos controles de WebPart é necessário definir no método público do controle o atributo Personalizable, veja como:
[Personalizable]
public string PostalCode
{
&nbsp; get
&nbsp; {
&nbsp;&nbsp;&nbsp; Return _postalCode;
&nbsp; }
&nbsp; set
&nbsp; {
&nbsp;&nbsp;&nbsp; _postalCode = value;
&nbsp; }
}
Enabling Shared Personalization
A personalização de WebParts são habilitadas por padrão e os usuários autenticados, conseguem personalizar uma WebPart sem qualquer configuração especial. Porém essas personalizações são feitas a nível de usuário, onde cada usuário visualiza somente sua mudança.Caso queria dar permissão para algum usuário, como o webmaster do site altere a personalização de qualquer usuário, isto é possível. Basta habilitar a personalização compartilhada no web.config.
Dentro da sessão &lt;system.web&gt;, adicione a sessão &lt;authorization&gt;, então adicione o elemento &lt;allow&gt; para especificar qual usuário ou usuário tem acesso a personalização compartilhada.
&lt;authorization&gt;
&nbsp; &lt;allow verbs="enterSharedScope" users="SomeUserAccount" roles="admin" /&gt;
&lt;/authorization&gt;
Desta forma os usuários podem alterar uma personalização e essas mudanças serão vistas por outros usuários. Disabling Personalization for a Page
Caso queria desabilitar a personalização em alguma página, basta definir a propriedade WebPartManager.Personalization.Enabled para false. Veja como:
&lt;asp:webPartManager ID="webPartManager1" runat="server"&gt;
&nbsp; &lt;Personalization Enabled="False" /&gt;
&lt;/asp:webPartManager&gt;