web user control

...now browsing by tag

 
 

ASP.NET Google Maps

Terça-feira, Abril 20th, 2010

google

O ASP.NET Google Maps é um Web User Control que implementa a API v2 do Google Maps.

Para utilizar esta API e este Web User Control é necessário registar-se aqui e obter uma chave de utilização.

A utilização deste controlo é em tudo semelhante ao ASP.NET Bing Maps, é apenas executar o Drag & Drop do controlo na página de implementação e configurar as propriedades do controlo.

Como utilizar?

Substituir no ficheiro GoogleMapsControl.ascx “YOU_KEY” pela chave que lhe foi atribuída durante o processo de registo na API do Google Maps.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="GoogleMapsControl.ascx.cs" Inherits="GoogleMaps.GoogleMaps.GoogleMapsControl" %>

<script type="text/javascript" src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOU_KEY"></script>
<script type="text/javascript" src="GoogleMaps/GoogleMaps.js"></script>
<div id="myMap"></div>

Implementação do Web User Control numa página Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GoogleMaps._Default" %>

<%@ Register src="GoogleMaps/GoogleMapsControl.ascx" tagname="GoogleMapsControl" tagprefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <uc1:GoogleMapsControl ID="GoogleMapsControl" runat="server" latitude="38.69052609303235" longitude="-9.297544956207275"
        pushPin="true" pushPinTitle="Sample Title" pushPinDescription="Sample Description" zoom="17" MapWidth="600px" MapHeight="400px"
        mapStyle="G_SATELLITE_MAP" />
    </div>
    </form>
</body>
</html>

Nas propriedades do controlo podemos definir um conjunto de funcionalidades disponibilizadas pela API do Google Maps, como o estilo de apresentação do mapa, definir a utilização de um marcador bem como o seu título e descrição.

Deixo aqui algumas imagens do controlo:

google_map_standard

google_satelite

google_satelite_2

google_terrain

Demo projecto de VS2008 e Web User Control disponível em:

http://aspnetgooglemaps.codeplex.com

ASP.NET Bing Maps

Terça-feira, Abril 20th, 2010

Bing_maps

O ASP.NET Bing Maps é mais um Web User Control que desenvolvi e decidi partilhar com a comunidade.

Por vezes damos por nós a fazer tarefas ou processos repetitivas durante o processo de desenvolvimento de aplicações, quando isso acontece é sinal que provavelmente podemos criar um controlo ou um fluxo genérico em substituição de todo esse trabalho. Os controlos genéricos são fáceis de manter actualizados, a actualização do controlo reflecte-se em todos os locais onde este é utilizado, são fáceis de implementar, são reutilizáveis e extensíveis.

Decidi criar um  Web User Control que implementa o Bing Maps porque necessitava de um controlo que eu pudesse controlar e alterar  programaticamente as propriedades de um mapa numa aplicação web.

Como utilizar?

projectlocation Criar no projecto de Visual Studio uma pasta com o nome BingMaps, adicionar os ficheiros BingMaps.ascx e BingMaps.js.

Depois, já na página onde se pretende implementar o controlo, é necessário registar o controlo como qualquer outro Web User Control (normalmente o Visual Studio faz isso por nós quando se executa o drag & drop do controlo sobre a página de implementação).

Exemplo de implementação:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="BingMaps._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<!-- Registo do controlo na página -->
<%@ Register src="BingMaps/BingMaps.ascx" tagname="BingMaps" tagprefix="UserControl" %>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Teste Bing Maps</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <UserControl:BingMaps runat="server" ID="BingMapContainer" runat="server" distanceUnit="Kilometers"  MapWidth="600px"
        MapHeight="400px" mapMode="Mode2D" mapStyle="BirdseyeHybrid" pushPin="true" pushPinTitle="Sample Title" zoom="1"
            pushPinDescription="Sample Description" latitude="38.69052609303235" longitude="-9.297544956207275"/>
    </div>
    </form>
</body>
</html>

Nas opções do controlo podemos definir o modo de apresentação do mapa (2D/3D), o estilo do mapa (Birds Eye, Road, Aerial, etc).

É possível definir um marcador, com um título e descrição,  para uma melhor indicação no mapa do local que pretendemos  apresentar.

Deixo aqui algumas imagens de demonstram as capacidades do controlo:

bingmaps_2d_birdseye

bingmaps_2d_aerial

bingmaps_2d_road

bingmaps_3d

Demo projecto de VS2008 e Web User Control disponível em:

http://aspnetbingmaps.codeplex.com

ASP.NET DataPager – EFDataPager

Terça-feira, Abril 20th, 2010

att9ae36 O EFDataPager é um Web User Control que permite paginação com Entity Framework ou qualquer outro tipo de repositório de dados. A grande diferença entre este DataPager e o controlo standard que é disponibilizado no Visual Studio é que ao contrário do controlo standard este apenas vai buscar ao repositório de dados a informação que está a ser apresentada na página seleccionada, o que permite uma melhoria substancial na performance de acesso a dados e tempos de carregamento da página web.

Exemplo de uma ListView com o DataPager do VS2008:

image_3

image_4

 

Como se pode verificar na Imagem1 e Imagem2 acima apresentadas, quando estamos a utilizar o Standard DataPager para controlar a paginação de uma ListView, este carrega todos os dados do repositório e posteriormente organiza-os por páginas.

O maior problema de este controlo é que, em cada postback efectuado, é carregada novamente para a ListView a informação de todas as páginas mesmo que, como podemos ver na imagem2, apenas estejam a ser apresentados 3 registos ao utilizador. Como consequência o tempo de carregamento da página da página é penalizado, pois são carregadas informações que não vão ser apresentadas ao utilizador,  o que gera um declínio na experiência de utilização.

 

Exemplo de uma ListView com o EFDataPager:

image_1

image_2

 

Por outro lado, ao utilizar o EFDataPager, apenas são carregados para a ListView os registos que são apresentados (Imagem3 e Imagem4), garantindo assim uma melhor experiência de utilização por parte do utilizador e um tempo de carregamento da página substancialmente menor.

Pode utilizar o EFDataPager com qualquer repositório de dados, incluindo com Entity Framework.

 

Implementação

Além de ser muito fácil de implementar o EFDataPager, é também um controlo extensível e facilmente personalizado para ir de encontro a necessidades mais específicas.

image_5

Para implementar o EFDataPager é necessário adicionar ao projecto o ficheiro ControloDataPager.ascx e o ficheiroPagerEventArgs.cs.

Depois é necessário, como em qualquer outro WebUserControl, registar o controlo na página em que este vai ser utilizado.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ControloListView.ascx.cs" Inherits="EFDataPager.UserControls.ControloListView" %>
<%@ Register src="ControloDataPager.ascx" tagname="ControloDataPager" tagprefix="UserControl" %>

<h1>Notícias</h1>

<div class="noticias-pager">
    <UserControl:ControloDataPager ID="ControloDataPager1" runat="server" ViewStateMode="Enabled" />
    <asp:Label ID="NumberOfRowsLoadedFromDataSource" runat="server"></asp:Label>
    <br />
    <asp:Label ID="NumberOfRowsLoadedFromDataSourceEN" runat="server"></asp:Label>
</div>

<asp:ListView ID="listviewNoticias" runat="server" >
    <LayoutTemplate>
        <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
    </LayoutTemplate>
    <ItemTemplate>
        <div class="noticias-title" >
            <h3><%#Eval("Titulo")%></h3>
        </div>
        <div class="body-container">
            <p><%#Eval("Descricao") %></p>
        </div>
    </ItemTemplate>
    <EmptyItemTemplate>
        <h1>Não existem notícias disponíveis neste momento.</h1>
    </EmptyItemTemplate>
</asp:ListView>

Depois é necessário implementar o método RegistarEventos, utilizá-lo no Page_Load, implementar os eventos registados no método  RegistarEventos e implementar o método CarregarDadosListview.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace EFDataPager.UserControls
{
    using EFDataPager.BusinessObjects;

    public partial class ControloListView : System.Web.UI.UserControl
    {

        protected void Page_Load(object sender, EventArgs e)
        {
            RegistarEventos();
            ControloDataPager1.PageSize = 5;
            ControloDataPager1.RowCount = GetNumberOfRows();

            if (!Page.IsPostBack)
            {
                CarregarDadosListview(ControloDataPager1.PageSize, 0);
            }
        }

        private void RegistarEventos()
        {
            ControloDataPager1.First    += new ControloDataPager.ListViewPagerFirstHandler(ControloDataPager1_First);
            ControloDataPager1.Previous += new ControloDataPager.ListViewPagerPreviousHandler(ControloDataPager1_Previous);
            ControloDataPager1.Next     += new ControloDataPager.ListViewPagerNextHandler(ControloDataPager1_Next);
            ControloDataPager1.Last     += new ControloDataPager.ListViewPagerLastHandler(ControloDataPager1_Last);
        }

        void ControloDataPager1_Last(object sender, PagerEventArgs e)
        {
            CarregarDadosListview(e.pageSize, e.currentRow);
        }

        void ControloDataPager1_Next(object sender, PagerEventArgs e)
        {
            CarregarDadosListview(e.pageSize, e.currentRow);
        }

        void ControloDataPager1_Previous(object sender, PagerEventArgs e)
        {
            CarregarDadosListview(e.pageSize, e.currentRow);
        }

        void ControloDataPager1_First(object sender, PagerEventArgs e)
        {
            CarregarDadosListview(e.pageSize, e.currentRow);
        }

        private void CarregarDadosListview(int pageSize, int currentRow)
        {
            var data = new DadosMock();
            listviewNoticias.DataSource = data.ObterDadosMock(pageSize, currentRow).ToArray();
            listviewNoticias.DataBind();

            var nRows = data.ObterDadosMock(pageSize, currentRow).ToArray().Count();
            NumberOfRowsLoadedFromDataSource.Text = string.Format("Número de elementos carregados: {0}", nRows);
            NumberOfRowsLoadedFromDataSourceEN.Text = string.Format("Number of binded elements: {0}", nRows);
        }

        private int GetNumberOfRows()
        {
            var data = new DadosMock();
            return data.ObterRowCount();
        }
    }
}

 

Está classe é um Mock para simular o comportamento de um repositório de dados.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EFDataPager.BusinessObjects
{
    public class DadosMock
    {
        public int ID { get; set; }
        public string Titulo { get; set; }
        public string Descricao { get; set; }

        public DadosMock()
        {

        }

        public DadosMock(int id, string title, string desc)
        {
            this.Descricao = desc;
            this.ID = id;
            this.Titulo = title;
        }

        public IQueryable<DadosMock> ObterDadosMock()
        {
            var lista = new List<DadosMock>();

            for (int i = 0; i < 18; i++)
            {

                var item = new DadosMock(i, string.Format("Titulo {0}", i), string.Format("Descricao {0}", i));
                lista.Add(item);
            }

            return lista.ToArray().AsQueryable();
        }

        public IQueryable<DadosMock> ObterDadosMock(int pageSize, int currentRow)
        {
            var lista = new List<DadosMock>();

            //only for generate test data
            for (int i = 0; i < 18; i++)
            {
                var item = new DadosMock(i, string.Format("Titulo {0}", i), string.Format("Descricao {1}", i, i));
                lista.Add(item);
            }

            return lista.ToArray().Skip(currentRow).Take(pageSize).AsQueryable();
        }

        public int ObterRowCount()
        {
            return ObterDadosMock().Count();
        }
    }
}

Com o recurso ao linq, podemos facilmente controlar a paginação dos dados pedidos ao repositório de dados através dos métodos Skip e Take.

Demo: http://blastersystems.com/efdatapager/

O EFDataPager e o projecto vs2008 de teste estão disponíveis em:

http://efdatapager.codeplex.com/

ASP.NET jQuery MessageBox

Terça-feira, Março 9th, 2010

4qjbsb5pxk1lp7f1pf66w3ls2a O ASP.NET MessageBox  é um Web User Control que integra a framework jQuery , é um controlo extensível que possibilita várias formas diferentes de apresentar MessageBox’s ao utilizador, utilizando duas tecnologias que em conjunto permitem a construção de um controlo dinâmico, extensível e de agradável utilização.

Disponível em http://jquerymessagebox.codeplex.com

Nesta primeira versão o controlo permite dois tipos diferentes de messagebox, uma do tipo “bubble” e outra standard.

O controlo possibilita a criação automática de um botão para interagir com o controlo, no entanto este é apenas opcional e pode-se desligar esta funcionalidade facilmente.

O design do controlo assenta nos plugins de jquery jQueryUI e plugin BlockUI, apenas com alguma modificações para estes se integrarem melhor num Web User Control de ASP.NET.

Vou passar agora a exemplificar a utilização do ASP.NET jQuery MessageBox com um exemplo para a MessageBox do tipo buble:

 

Página de exemplo que vai utilizar o controlo (default.aspx)

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="jQueryMessageBox._Default" %>
<%@ Register src="WebUserControl/MessageBoxControl.ascx" tagname="MessageBoxControl" tagprefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <uc1:MessageBoxControl ID="MessageBoxControl1" runat="server" />
    </div>
    </form>
</body>
</html>

 

 

Code behind (default.aspx.cs)


using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;

namespace jQueryMessageBox
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            MessageBoxControl1.Title = "Test jQueryMessageBox";
            MessageBoxControl1.NameBtn = "Open Message";
            MessageBoxControl1.NameBtnMessageBox = "Close";
            MessageBoxControl1.tipo =
                WebUserControl.MessageBoxControl.typeMessageBox.growlMessageBox;

            MessageBoxControl1.Text = "Login succeeded!";
        }

        protected void btn_Click(object sender, EventArgs e)
        {
            MessageBoxControl1.btn_Click(sender, e);
        }
    }
}

 

Ao carregar no botão visível na imagem, pode-se visualizar a mensagem dirigida ao utilizador.

bubble_message

 

Por outro lado se o tipo de mensagem que nos interessa mostrar ao utilizador contém muita informação e obriga a uma maior atenção por parte do utilizador, podemos utilizar este tipo de MessageBox, alterando o tipo de mensagem a apresentar e alterando o ficheiro default.aspx.cs:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;

namespace jQueryMessageBox
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            MessageBoxControl1.Title = "Test jQueryMessageBox";
            MessageBoxControl1.NameBtn = "Open Message";
            MessageBoxControl1.NameBtnMessageBox = "Close";

            /*Alteração do tipo de MessageBox*/
            MessageBoxControl1.tipo =
                WebUserControl.MessageBoxControl.typeMessageBox.centerMessageBox;

            var dados = new StringBuilder();

            dados.Append("jQuery is a lightweight cross-browser JavaScript library that emphasizes interaction between JavaScript and HTML. It was released in ");
            dados.Append("January 2006 at BarCamp NYC by John Resig. Used by over 27% of the 10,000 most visited websites, jQuery is the most popular ");
            dados.Append("JavaScript library in use today.");
            dados.Append("jQuery is free, open source software, dual-licensed under the MIT License and the GNU General Public License, Version 2. jQuerys ");
            dados.Append("syntax is designed to make it easier to navigate a document, select DOM elements, create animations, handle events, and develop Ajax ");
            dados.Append("applications. jQuery also provides capabilities for developers to create plugins on top of the JavaScript library. Providing this option, ");
            dados.Append("developers are able to create abstractions for low-level interaction and animation, advanced effects and high-level, theme-able widgets. This");
            dados.Append("contributes to the creation of powerful and dynamic web pages.");
            dados.Append("Microsoft and Nokia have announced plans to bundle jQuery on their platforms, Microsoft adopting it initially within Visual Studio for use ");
            dados.Append("within Microsoft ASP.NET AJAX framework and ASP.NET MVC Framework whilst Nokia will integrate it into their Web Run-Time platform.");

            MessageBoxControl1.Text = dados.ToString();
        }

        protected void btn_Click(object sender, EventArgs e)
        {
            MessageBoxControl1.btn_Click(sender, e);
        }
    }
}

 

E o resultado ao executar o click no mesmo botão é apresentado em baixo:

center_meaage

 

O projecto de teste e o código fonte do controlo está disponível em http://jquerymessagebox.codeplex.com

 

Fontes de informação úteis:

http://weblogs.asp.net/scottgu/archive/2008/11/21/jquery-intellisense-in-vs-2008.aspx

http://jquery.com/

http://jqueryui.com/