Desenvolvedores.Net - TechBlog

Category Archives: Ajax

Criando componentes no lado Servidor

1
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
20 de junho de 2014

CriandoComponentes

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

Criando componentes no lado Servidor

Ao desenvolvermos um componente utilizando como base um componente já criado no Ext.NET, ganhamos de brinde toda a reutilização deste, por exemplo: – Nosso componente já pode ser utilizado em WebForm,  em ASP MVC, com a engine Razor, no código markup, etc.

Outra vantagem desta abordagem é que quando estudamos o código do Ext.NET, você poderá entender como eles criam seus componentes com base nos componentes Ext JS,e não necessariamente você precisa ser um conhecedor profundo do Ext JS.

Como vantagem também, podemos citar que você pode desenvolver seu componente em qualquer linguagem .NET que você tenha familiaridade e não precisa aprender a ser um ninja em javascript, pois todo o javascript será gerado para o lado cliente.

Neste tópico, iremos focar na criação do componente do lado servidor, na utilização do lado cliente, e como criar seus próprios métodos que podem ser acessados do lado cliente e lado servidor.

Antes de começarmos…

Vamos definir nossas abstrações e nossos objetos de validação do componente. Como neste artigo eu irei criar dois componentes para inserção de texto. Iremos criar uma abstração para tipos texto e uma classe de resultado da validação.

Classe ValidateResult

/// <summary>
/// Classe que determina o resultado da validação feita e retorna.
/// </summary>
public sealed class ValidateResult
{
	#region locais
	bool valid = true;
	string invalidMessage = "";
	#endregion

	#region propriedades
	/// <summary>
	/// Se true, o valor inserido no componente é valido.
	/// </summary>
	public bool Valid
	{
		get { return valid; }
		private set { valid = value; }
	}

	/// <summary>
	/// Se não for válido é necessário informar uma mensagem de erro
	/// </summary>
	public string InvalidMessage
	{
		get { return invalidMessage; }
		private set { invalidMessage = value; }
	}
	#endregion

	#region Construtores
	/// <summary>
	/// Inicia o resultado da validação
	/// </summary>
	/// <param name="valid">true/false para válido ou não.</param>
	/// <param name="invalidMessage">Se "valid" for verdadeiro, é obrigatório informar a mensagem.</param>
	/// <exception cref="ArgumentException">Se "valid" for verdadeiro, e o parâmetro "invalidMessage"
	/// não for informado. Esta exceção será lançada.</exception>
	public ValidateResult(bool valid, string invalidMessage = "")
	{
		this.valid = valid;

		if(!valid && String.IsNullOrEmpty(invalidMessage))
			throw new ArgumentException("Se \"valid\" for definido como false. É obrigatório informar uma mensagem de erro em \"invalidMessage\".", "invalidMessage");

		this.invalidMessage = invalidMessage;
	}
	#endregion
}

Abstração para campos do tipo texto (TextFieldBase)

public abstract class TextFieldBase: Ext.Net.TextField, IValidator
{
	public TextFieldBase()
		: base()
	{

	}

	#region IValidator Members
	public string ErrorMessage { get; set; }
	public bool IsValid { get; set; }

	public override void Validate()
	{
		ValidateResult result = Validate(Text);
		IsValid = result.Valid;
		ErrorMessage = result.InvalidMessage;

		if(IsValid)
			MarkAsValid();
		else
			MarkInvalid(ErrorMessage);
	}

	/// <summary>
	/// Faz a validação do componente e retorna true se o texto do componente for válido, caso contrário false
	/// </summary>
	/// <param name="value">valor que deverá ser validado</param>
	/// <returns></returns>
	protected abstract ValidateResult Validate(string value);
	#endregion
}
note-taking No código em destaque, vejam que eu fiz uma herança da classe “Ext.Net.TextField” e da interface “IValidator”.
Desta forma eu já herdo todas as funcionalidades de um componente do tipo “TextField” e apenas ajusto para a minha necessidade. a herança da interface “IValidator” é apenas para a implementação dos métodos de validação.

Ok! Definimos a nossa abstração. Vamos agora criar o nosso componente.

Meu primeiro componente

Vamos criar um componente bem simples. Um campo de CEP, que irá fazer uma validação e será utilizado em uma página.

CEPField

public class CEPField: TextFieldBase
{
	#region Contrutores
	public CEPField()
		: base()
	{
		DirectEvents.Blur.Event += new ComponentDirectEvent.DirectEventHandler(Blur_Event);
		AllowBlank = false;
		this.IsRemoteValidation = true;
		this.RemoteValidation.Validation += new RemoteValidationDirectEvent.RemoteValidationEventHandler(RemoteValidation_Validation);
		FieldLabel = "CEP";
	}
	#endregion

	#region Tratadores de eventos
	void RemoteValidation_Validation(object sender, RemoteValidationEventArgs e)
	{
		Validate();
		e.Success = IsValid;
		e.ErrorMessage = ErrorMessage;
	}

	void Blur_Event(object sender, DirectEventArgs e)
	{
		this.SetValue(Format.CEP(Text));
	}
	#endregion

	#region overrides

	public override void SetValue(object value)
	{
		Validate();

		base.SetValue(value);
		if(!string.IsNullOrEmpty(ClientID))
			Ext.Net.X.AddScript(ClientID +
				".isValid = function(){return " + IsValid.ToString().ToLower() + ";};");
	}

	public override int MaxLength
	{
		get { return 9; }
		set { base.MaxLength = 9; }
	}
	#endregion

	#region IValidator Members
	protected override ValidateResult Validate(string value)
	{
		if(AllowBlank && String.IsNullOrEmpty(value))
			return new ValidateResult(true);

		value = Utilities.OnlyNumbers(value);

		if(String.IsNullOrEmpty(value))
			return new ValidateResult(false, "O CEP não pode ser vazio ou não foi digitado corretamente.");

		//permite somente números
		if(value.Count(w => !Char.IsNumber(w)) > 0)
			return new ValidateResult(false, "O CEP não é válido.");

		//para ser válido tem que ter 8 caracteres
		if(value.Length != 8)
			return new ValidateResult(false, "O CEP não é válido.");

		return new ValidateResult(true);
	}
	#endregion
}
question Hm! OK! Eu criei meu componente. Mas como eu faço para chamá-lo em uma página asp? É possível utilizar a mesma marcação que temos para o Ext.NET, utilizando a tag “<ext>“?

R: Sim, é possível, com um pequeno ajuste no nosso arquivo “web.config”.
Dentro da tag “” devemos inserir a linha em destaque, logo abaixo

<pages>
  <controls>
	<!--Indica que toda página criada irá ter a diretiva "ext" como padrão para ser usada como marcação na criação.-->
	<add assembly="Ext.Net" namespace="Ext.Net" tagPrefix="ext"/>
	<add assembly="Ext.Net.Tutorial" namespace="Ext.Net.Tutorial.ComponentModel" tagPrefix="tut"/>
  </controls>
</pages>
  • Esta linha indica que um assembly deverá ser adicionado; “add assembly“; para todas as páginas criadas;
  • Os controles que estão no “namespace” …
  • Deverão ser associados com o prefixo;”tagPrefix“; “tut“;

Pronto. Agora podemos utilizar o nosso componente apenas escrevendo a tag

<tut:CEPField ID="CEPField1" runat="server" FieldLabel="Informe seu CEP">
 </tut:CEPField>

O próximo componente que será criado é um “CurrencyField“, um campo para inserir valores monetários. Vamos ver o código do mesmo, e explicar logo em seguida.

public class CurrencyField: TextFieldBase
{
	#region Construtores
	public CurrencyField()
		: base()
	{
		//-------------------------------------------------------------------------
		// Define que só podemos digitar números de 0-9 e a vírgula.
		//-------------------------------------------------------------------------
		MaskRe = "/[0-9\\,]/";

		//-------------------------------------------------------------------------
		// Define o método javascript que irá ser chamado ao receber o foco
		//-------------------------------------------------------------------------
		Listeners.Focus.Handler = "this.setRawValue(this.getNumber());this.selectText();";

		//-------------------------------------------------------------------------
		// Define o método que será chamado ao perder o foco
		//-------------------------------------------------------------------------
		Listeners.Blur.Handler = "this.setValue(this._getValue(this.getValue()));";

		//-------------------------------------------------------------------------
		// Define que o valor deverá ser alinhado a direta do componente
		//-------------------------------------------------------------------------
		FieldStyle = "text-align:right;";
	}

	#endregion

	#region Overrides
	public override ConfigItemCollection CustomConfig
	{
		get
		{
			ConfigItemCollection result = base.CustomConfig;
			string curSbl = "R$";

			#region _getValue
			//-------------------------------------------------------------------------
			// Criando o método _getValue para o lado cliente.
			//-------------------------------------------------------------------------
			ConfigItem it = new ConfigItem("_getValue", @"function(v){
				return MyApp.Util.Format.currency(this.cleanValue(v), 2,'" + curSbl + @"');
				}
			");

			result.Add(it);
			#endregion

			#region getNumber
			//-------------------------------------------------------------------------
			// Criando o método getNumber para o lado cliente.
			//-------------------------------------------------------------------------
			it = new ConfigItem("getNumber", @"function(){
				if(this.number === undefined || this.number == 0)
					this.number = MyApp.Convert.toNumber(this.getValue());

				return this.number;
				}
			");

			result.Add(it);
			#endregion

			#region setValue
			//-------------------------------------------------------------------------
			// Substituindo o método setValue, com a nossa definição
			//-------------------------------------------------------------------------
			it = new ConfigItem("setValue", @"function(v){
				v = this._getValue(v);
				this.setRawValue(v);
				this.number = MyApp.Convert.toNumber(this.getValue());
				this.text = v;
				}
			");

			result.Add(it);
			#endregion

			#region cleanValue
			//-------------------------------------------------------------------------
			// Criando o método cleanValue para o lado cliente.
			//-------------------------------------------------------------------------
			it = new ConfigItem("cleanValue", @"function(v){
					if(v){
						return MyApp.Util.Format.number(v, 2);
					}else
						return 0;
				}
			");

			result.Add(it);
			#endregion

			return result;
		}
	}

	public override void SetValue(object value)
	{
		this.SetValue(value.ToString());
		base.SetValue(Number);
	}
	protected void SetValue(string text)
	{
		Text = text;
		Number = Convert.ToDouble(text);
	}
	#endregion

	#region Propriedades
	public virtual double Number
	{
		get { return Utilities.Convert.ToDouble(base.Text); }
		set { base.Text = value.ToString(); }
	}
	#endregion

	#region IValidator members
	protected override ValidateResult Validate(string value)
	{
		double d = Utilities.Convert.ToDouble(value);

		if(!AllowBlank && d == 0)
			return new ValidateResult(false, "É obrigatório informar o valor monetário.");

		return new ValidateResult(true);
	}
	#endregion
}

Neste código foi apresentado um meio de você criar seus próprios métodos javascript e associá-los ao seus componentes.

Para isto, utilizamos o que chamamos de “CustomConfig“, veja nas linhas em destaque.

note-taking O objeto “Ext.Net.ConfigItem“, permite que você defina métodos e propriedades para seus controles. Feito isso, você pode acessar em um código javascript.

var v = App.MyComponent._getValue();

Entendendo o objeto Ext.Net.ConfigItem

Este objeto tem a finalidade de vincular seus métodos javascript aos componentes Ext.NET, isso se torna útil quando estamos criando nossos próprios componentes.

Possui 3 propriedades importantes:

  • Name: Define o nome do método ou propriedade que será exposto;
  • Value:  Define o valor que será representado pelo sue método ou propriedade;
  • Mode: O mode pode ser:
    • Auto: O Ext.NET tentará detectar o tipo e se não for capaz, A propriedade “Value” será encapsulada como uma string, ou como um número, de acordo com seu tipo;
    • Raw: A propriedade “Value” será exposta como está;
    • Value: Valor da propriedade ou código do método;
note-taking Por convenção, nomeie seus métodos utilizando “camelCase“. Se você escrever o nome do método em “UpperCase” o Ext.NET irá converter para “camelCase“, mantendo a convenção de nomes definida pelo javascript.

 


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Trabalhando com dados, Combobox e GridPanel

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (1 votos, média: 4,00 de 5)
Loading...
19 de junho de 2014

Dados_Combobox_GridPanel

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

Trabalhando com dados, Combobox e GridPanel

À essa altura do tópico, já temos conhecimento sobre os componentes, “DirectMethod“, “DirectEvents“, “Listeners“, entre outras coisas. Então é hora de entendermos como podemos exibir os dados aos nossos usuários. Neste tópico eu vou apresentar à vocês a classe “Store“. Então, vamos lá.

Store

O “Store” é um componente que trata os dados entre o cliente e o servidor, normalmente utilizado com componentes do tipo “Grids” e “Comboboxes“. Um “Store” tem a capacidade de filtrar e ordenar os dados, seja local ou remotamente.

Este por sua vez, tem dois pontos importantes:

  • Um “Model“, onde definimos os tipos de dados, nomes de campos, validações, entre outros;
  • Um “Proxy“, responsável pelas requisições entre cliente e servidor, e manter os dados atualizados no lado cliente;
note-taking O componente “Store” tem vários tipos de subclasses, como “JsonStore“, “ArrayStore“, “XMLStore” entre outros. Neste tópico iremos ver os dois mais utilizados “JsonStore” e “ArrayStore“.Mas não se preocupe, quando Ext.NET gera as classes proxyes, automaticamente já é gerado todo o código Ext Js que irá tratar cada tipo de “Store“.

Models

Um “Model” define os dados que o “Store” irá tratar. Em versões anteriores do Ext.NET, este era conhecido como “Record“. No “Model” podemos definir os dados, as validações, nomes para cada campo e formato.

Proxy

Um “Proxy” é utilizado para manter os dados, é uma abstração para o mecanismo de tratamento dos dados e se divide em dois tipos:

  • Client-Side Proxies;
    • MemoryProxy: É um simples “proxy” que mantem os dados na memória do navegador;
    • LocalStorageProxySessionStorageProxy: Usam a nova definição de armazenamento do HTML5. Não funcionam em navegadores mais antigos, pois estes não aceitam HTML5
    • (Eu ainda não estou muito familiarizado com o HTML5 e as novas definições de proxy para o mesmo. Para evitar informação errada, vou parar por aqui 🙂 )

  • Server-Side Proxies;
    • AjaxProxy: Este é um “proxy” de propósito geral, que aceita objetos do tipo array, cada índice é um nome de coluna definido no “model“;
    • JsonPProxy: Permite requisições AJAX “cross-domain“;
    • PageProxy: É um “proxy” que trabalha na página e permite a ligação com eventos no lado servidor;

Entendido o processo de acesso utilizando “Stores”, vamos botar em prática o que aprendemos.

Não se preocupe com os detalhes do código, vamos nos ater apenas ao uso do “Store” e suas peculiaridades.

Antes de começar

Para os dois exemplos, temos que preparar o nosso ambiente antes de começar, para isso, crie dois arquivos de estilo.

combobox.css

.list-item
{
    font: normal 11px tahoma, arial, helvetica, sans-serif;
    padding: 3px 10px 3px 10px;
    border: 1px solid #fff;
    border-bottom: 1px solid #eeeeee;
    white-space: normal;
    color: #555;
}

.list-item h3
{
    display: block;
    font: inherit;
    font-weight: bold;
    margin: 0px;
    color: #222;
}

gridpanel.css

.x-grid-cell-fullName .x-grid-cell-inner
{
    font-family: tahoma, verdana;
    display: block;
    font-weight: normal;
    font-style: normal;
    color: #385F95;
    white-space: normal;
}

.x-grid-rowbody div
{
    margin: 2px 5px 20px 5px !important;
    width: 99%;
    color: Blue;
}

.x-grid-row-expanded td.x-grid-cell
{
    border-bottom-width: 0px;
}

Estes dois arquivos serão responsáveis pela apresentação dos dados no lado cliente.

Continuando …

Exibindo os dados…

Vamos utilizar uma lista de objetos para exibir e tratar os dados do lado cliente. Nos dois exemplos iremos configurar um “Store” para uma “Combbox” e para  uma “GridPanel“.

Veja os exemplos:

Atente apenas ao uso do “Store”. O Resto do código será explicado posteriormente.

GridPanel

ASPX Code

<head id="Head1" runat="server">
    <title>Tutorial Ext.NET</title>
    <link href="../css/gridpanel.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="../Scripts/GridPanel.js"></script>
</head>
<body>
    <form id="Form1" runat="server">
    <ext:ResourceManager ID="ResourceManager1" runat="server" />
    <ext:Window ID="Window1" runat="server" Collapsible="true" Maximizable="true" Icon="Money"
        Title="Orders List" Width="1300" Height="600" X="50" Y="50" Layout="Fit" Closable="false">
        <Items>
            <ext:GridPanel ID="GridPanel1" runat="server" Title="Employees" Frame="true" Header="false"
                Border="false">
                <Store>
                    <ext:Store ID="Store1" runat="server" OnReadData="Store1_ReadData">
                        <Model>
                            <ext:Model ID="Model1" runat="server">
                                <Fields>
                                    <ext:ModelField Name="CustomerID" />
                                    <ext:ModelField Name="EmployeeID" />
                                    <ext:ModelField Name="OrderDate" />
                                    <ext:ModelField Name="RequiredDate" />
                                    <ext:ModelField Name="ShippedDate" />
                                    <ext:ModelField Name="ShipVia" />
                                    <ext:ModelField Name="Freight" />
                                    <ext:ModelField Name="ShipName" />
                                    <ext:ModelField Name="ShipAddress" />
                                    <ext:ModelField Name="ShipCity" />
                                    <ext:ModelField Name="ShipRegion" />
                                    <ext:ModelField Name="ShipPostalCode" />
                                    <ext:ModelField Name="ShipCountry" />
                                </Fields>
                            </ext:Model>
                        </Model>
                    </ext:Store>
                </Store>
                <ColumnModel ID="ColumnModel1" runat="server">
                    <Columns>
                        <ext:Column ID="Column0" runat="server" Text="CustomerID" Width="150" DataIndex="CustomerID">
                        </ext:Column>
                        <ext:Column ID="Column1" runat="server" DataIndex="EmployeeID" Text="EmployeeID"
                            Width="150" />
                        <ext:DateColumn ID="Column2" runat="server" DataIndex="OrderDate" Text="Order Date"
                            Width="150" Format="dd/MM/yyyy" />
                        <ext:DateColumn ID="DateColumn1" runat="server" DataIndex="RequiredDate" Text="Required Date"
                            Width="110" Format="dd/MM/yyyy" />
                        <ext:DateColumn ID="DateColumn2" runat="server" DataIndex="ShippedDate" Text="Shipped Date"
                            Width="110" Format="dd/MM/yyyy" />
                        <ext:Column ID="Column3" runat="server" DataIndex="ShipVia" Text="Ship Via" Width="150" />
                        <ext:Column ID="Column4" runat="server" DataIndex="Freight" Text="Freight" Width="100" />
                    </Columns>
                </ColumnModel>
                <View>
                    <ext:GridView ID="GridView1" runat="server">
                        <GetRowClass Handler="return 'x-grid-row-expanded';" />
                    </ext:GridView>
                </View>
                <SelectionModel>
                    <ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" />
                </SelectionModel>
                <Features>
                    <ext:RowBody ID="RowBody1" runat="server">
                        <GetAdditionalData Handler="orig.rowBody = '<div><span style=\'color: red\'>Ship Information</span>' + '</br/>' + data.ShipName + '</br/>' + data.ShipAddress + '</br/>' + data.ShipCity + (data.ShipRegion == null ? '' : ' - ' + data.ShipRegion) + '</br/>' + (data.ShipPostalCode == null ? '' : data.ShipPostalCode + '</br/>') + data.ShipCountry + '</div>'; orig.rowBodyColspan = record.fields.getCount();" />
                    </ext:RowBody>
                </Features>
                <BottomBar>
                    <ext:PagingToolbar ID="PagingToolbar1" runat="server">
                        <Items>
                            <ext:Label ID="Label1" runat="server" Text="Page size:" />
                            <ext:ToolbarSpacer ID="ToolbarSpacer1" runat="server" Width="10" />
                            <ext:ComboBox ID="ComboBox1" runat="server" Width="80">
                                <Items>
                                    <ext:ListItem Text="1" />
                                    <ext:ListItem Text="2" />
                                    <ext:ListItem Text="10" />
                                    <ext:ListItem Text="20" />
                                </Items>
                                <SelectedItems>
                                    <ext:ListItem Value="10" />
                                </SelectedItems>
                                <Listeners>
                                    <Select Handler="#{GridPanel1}.store.pageSize = parseInt(this.getValue(), 10); #{GridPanel1}.store.reload();" />
                                </Listeners>
                            </ext:ComboBox>
                        </Items>
                        <Plugins>
                            <ext:ProgressBarPager ID="ProgressBarPager1" runat="server" />
                        </Plugins>
                    </ext:PagingToolbar>
                </BottomBar>
            </ext:GridPanel>
        </Items>
    </ext:Window>
    </form>
</body>
note-taking Atenção às linhas em destaque, nestas linhas, estão as definições do “Store”, do “Model” e do “Proxy”.
As definições do modelo estão na tag “<Model>” e dentro de cada tag “<Model>” temos para cada campo a definição “<ModelField>”, onde definimos o nome da propriedade, ou campo, do objeto que será usado no componente “<ColumnModel>” que é definido logo abaixo.
Dentro do “<ColumnModel>” utilizamos a propriedade “DataIndex”, esta tem que ser o mesmo nome definido em “<Model>”, e será este nome que deverá ser usado em seus código javascript.

 

question Mas onde está a definição do <Proxy> dentro do <Store>?

R: Como não definimos um <Proxy> e estamos utilizando uma requisição de página, método “OnReadData=’Store1_ReadData'”, automaticamente será definido como proxy um “PageProxy”.

Code Behind

public partial class GridPanelArray: System.Web.UI.Page
{
	protected void Page_Load(object sender, EventArgs e)
	{
		if(!X.IsAjaxRequest)
		{
			this.BindData();
		}
	}

	protected void Store1_ReadData(object sender, StoreReadDataEventArgs e)
	{
		BindData();
	}

	private void BindData()
	{
		Store store = this.GridPanel1.GetStore();

		store.DataSource = this.Data;
		store.DataBind();
	}

	List<Order> Data
	{
		get
		{
			return Order.Find<Order>();
		}
	}
}

No código acima, temos o método que será chamado quando o “Store” requisitar os dados para o servidor, “Store1_ReadData“. Este método por sua vez chama o método “BindData()“, dentro do método “BindData()”, é carregado uma lista de pedidos (“Order”) e retornados para a propriedade “DataSource” do “Store“, e logo em seguida fazemos a ligação dos dados chamando o método “Store.DataBind()“.

ComboBox

<ext:ComboBox ID="ComboBox4" runat="server" FieldLabel="Selecione vários colaboradores"
	DisplayField="FirstName" Width="320" LabelWidth="130" QueryMode="Local" TypeAhead="true"
	MultiSelect="true">
	<Store>
		<ext:Store ID="Store4" runat="server" Data="<%# ArrayOfEmployees %>" AutoDataBind="true">
			<Model>
				<ext:Model ID="Model4" runat="server">
					<Fields>
						<ext:ModelField Name="EmployeeID" />
						<ext:ModelField Name="FirstName" />
						<ext:ModelField Name="LastName" />
					</Fields>
				</ext:Model>
			</Model>
			<Reader>
				<ext:ArrayReader />
			</Reader>
		</ext:Store>
	</Store>
	<ListConfig>
		<ItemTpl ID="ItemTpl1" runat="server">
			<Html>
				<div class="list-item">
							<h3>ID: {EmployeeID}</h3>
							{FirstName} {LastName}
					</div>
			</Html>
		</ItemTpl>
	</ListConfig>
</ext:ComboBox>

Code Behind

public object ArrayOfEmployees
{
	get
	{
		object result = (from e in Employee.Find<Employee>()
						 select new object[]
						 {
							 e.EmployeeID,
							 e.FirstName,
							 e.LastName,
						 }).ToArray();

		return result;

	}
}

No exemplo do combobox não mudou muita coisa, definimos um “Model” com o mapeamento dos campos, mas  … Temos uma diferença, definimos que o nosso “Reader” irá utilizar uma “ArrayReader”, logo temos que retornar um “Array” de objetos, isto ficou a cargo da propriedade  “ArrayOfEmployees“. A chamada também foi modificada, não usamos o evento “OnDataRead“, e sim a propriedade “Data” com um diretiva ASPX <%# ArrayOfEmployees %>, em ASPX esta diretiva diz ao interpretador para retornar um objeto “datasource“.

Utilizando um DataSource.

O Ext.NET aceita diversos tipos de “DataSources”:

  • LinqDataSource: Aceita comando do tipo “LINQ”;
  • ObjectDataSource: Aceita classes definidas dentro da nossa aplicação. Eu gosto deste 🙂
  • SqlDataSource: Aceita comando do tipo SQL;
  • XmlDataSource: Aceita arquivos do tipo XML. Este datasource requer que seja criado um “Transform” para que possa compreender os dados;
note-taking Você pode usar diversos “datasources” em uma mesma página, para isso basta definir o ID de cada um, e ao utilizar em um “Store“, define o ID do “datasource” na propriedade “Store.DataSourceID“. Cada Store só pode ter um “datasource” definido.
Para saber mais: http://examples.ext.net/#/search/datasource

No exemplo abaixo iremos ver o “ObjectDataSource” em ação.

ASPX Code

<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="Find" TypeName="Ext.Net.Tutorial.Data.Order" />
<ext:Window ID="Window1" runat="server" Collapsible="true" Maximizable="true" Icon="Money"
	Title="Orders List" Width="1300" Height="600" X="50" Y="50" Layout="Fit" Closable="false">
	<Items>
		<ext:GridPanel ID="GridPanel1" runat="server" Title="Employees" Frame="true" Header="false"
			Border="false">
			<Store>
				<ext:Store ID="Store1" runat="server" DataSourceID="ObjectDataSource1">
					<Model>
						<ext:Model ID="Model1" runat="server">
							<Fields>
								<ext:ModelField Name="CustomerID" />
								<ext:ModelField Name="EmployeeID" />
								<ext:ModelField Name="OrderDate" />
								<ext:ModelField Name="RequiredDate" />
								<ext:ModelField Name="ShippedDate" />
								<ext:ModelField Name="ShipVia" />
								<ext:ModelField Name="Freight" />
								<ext:ModelField Name="ShipName" />
								<ext:ModelField Name="ShipAddress" />
								<ext:ModelField Name="ShipCity" />
								<ext:ModelField Name="ShipRegion" />
								<ext:ModelField Name="ShipPostalCode" />
								<ext:ModelField Name="ShipCountry" />
							</Fields>
						</ext:Model>
					</Model>
				</ext:Store>
			</Store>
			<ColumnModel ID="ColumnModel1" runat="server">
				<Columns>
					<ext:Column ID="Column0" runat="server" Text="CustomerID" Width="150" DataIndex="CustomerID">
					</ext:Column>
					<ext:Column ID="Column1" runat="server" DataIndex="EmployeeID" Text="EmployeeID"
						Width="150" />
					<ext:DateColumn ID="Column2" runat="server" DataIndex="OrderDate" Text="Order Date"
						Width="150" Format="dd/MM/yyyy" />
					<ext:DateColumn ID="DateColumn1" runat="server" DataIndex="RequiredDate" Text="Required Date"
						Width="110" Format="dd/MM/yyyy" />
					<ext:DateColumn ID="DateColumn2" runat="server" DataIndex="ShippedDate" Text="Shipped Date"
						Width="110" Format="dd/MM/yyyy" />
					<ext:Column ID="Column3" runat="server" DataIndex="ShipVia" Text="Ship Via" Width="150" />
					<ext:Column ID="Column4" runat="server" DataIndex="Freight" Text="Freight" Width="100" />
				</Columns>
			</ColumnModel>
			<View>
				<ext:GridView ID="GridView1" runat="server">
					<GetRowClass Handler="return 'x-grid-row-expanded';" />
				</ext:GridView>
			</View>
			<SelectionModel>
				<ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" />
			</SelectionModel>
			<Features>
				<ext:RowBody ID="RowBody1" runat="server">
					<GetAdditionalData Handler="orig.rowBody = '<div><span style=\'color: red\'>Ship Information</span>' + '</br/>' + data.ShipName + '</br/>' + data.ShipAddress + '</br/>' + data.ShipCity + (data.ShipRegion == null ? '' : ' - ' + data.ShipRegion) + '</br/>' + (data.ShipPostalCode == null ? '' : data.ShipPostalCode + '</br/>') + data.ShipCountry + '</div>'; orig.rowBodyColspan = record.fields.getCount();" />
				</ext:RowBody>
			</Features>
		</ext:GridPanel>
	</Items>
</ext:Window>
</form>
</body>

No código em destaque, acima, definimos o “ObjectDataSource” para o nosso “Store“, vamos explicar algumas propriedades:

  • ID: “ObjectDataSource1”: Define o nome do objeto “DataSource” que deverá ser utilizado no “Store“;
  • TypeName: “Ext.Net.Tutorial.Data.Order”: Define o nome do objeto que será instanciado pelo “DataSource”;
  • SelectMethod: “Find”: Nome do método que será chamado para popular o “DataSource”;

Nas outras linhas em destaque, como sempre, definimos o nosso “Model” e já estamos familiarizados com ele.

Utilizando um Proxy

Até que enfim… Falamos tanto do acesso aos dados, de diversas formas, que já estava esquecendo deste tal “proxy“. Vamos ver como trabalhar com o proxy. Para isso, iremos criar um “ASPX Hanlder“.

question Handler? O que é isso?

R: Os Handlers, são manipuladores responsáveis por tratar as requisições HTTP, não têm interface com usuário e são executados de forma síncrona. Devem implementar a interface “System.Web.IHttpHandler“. Um exemplo de requisição que implementa a interface “System.Web.IHttpHandler” é a “System.Web.UI.Page“, que deve ser herdada para criar os formulários em ASPX. (Web Forms). Esta é quem define toda a interatividade com o usuário. OS “Handlers” são úteis quando precisamos de acessar dados do servidor, sem a intervenção do usuário.

Preparando o ambiente.

Antes de começarmos, iremos criar 3 “ASPX Handlers”:

  1. HandlerBase<T>: Abstração para o tratamento dos dados, pois o código de tratamento é semelhante para todos os outros “handlers” que tratam o acesso aos dados.
  2. EmployeeHandler: É o “handler” responsável por exibir os dados dos colaboradores;
  3. OrderHandler: É o “handler” responsável por exibir os dados dos pedidos;

Abstração HandlerBase

public abstract class HandlerBase<T>: System.Web.IHttpHandler
	where T: IModelBase, new()
{
	public void ProcessRequest(HttpContext context)
	{
		//-------------------------------------------------------------------------
		// Definir o tipo de retorno da resposta da requisição.
		// Iremos retornar um objeto do tipo JSON
		//-------------------------------------------------------------------------
		context.Response.ContentType = "application/json";

		//-------------------------------------------------------------------------
		// Recuperar os parâmetros que foram passados pela requisição
		//-------------------------------------------------------------------------
		StoreRequestParameters storeParams = new StoreRequestParameters(context);

		//-------------------------------------------------------------------------
		// Paginar
		//-------------------------------------------------------------------------
		Paging<T> data = DataPaging(storeParams.Start, storeParams.Limit,
			storeParams.Sort.Count() > 0 ? storeParams.Sort[0].Property : "",
			storeParams.Sort.Count() > 0 ? storeParams.Sort[0].Direction.ToString() : "",
			storeParams.GridFilters);
		context.Response.Write(JSON.Serialize(data));
	}

	public bool IsReusable
	{
		get
		{
			return false;
		}
	}

	public static Paging<T> DataPaging(int start, int limit, string sort, string dir, FilterConditions fc)
	{
		List<T> data = DbContext.Find<T>(new T());

		#region Filtrar
		//-------------------------------------------------------------------------
		// Se foi definido alguma condição, temos que filtrar os registros
		//-------------------------------------------------------------------------
		if(fc != null && fc.Conditions.Count > 0)
		{
			foreach(FilterCondition condition in fc.Conditions)
			{
				Comparison comparison = condition.Comparison;
				string field = condition.Field;
				FilterType type = condition.Type;

				object value;
				switch(condition.Type)
				{
					case FilterType.Boolean:
						value = condition.Value<bool>();
						break;
					case FilterType.Date:
						value = condition.Value<DateTime>();
						break;
					case FilterType.List:
						value = condition.List;
						break;
					case FilterType.Numeric:
						if(data.Count > 0 && data[0].GetType().GetProperty(field).PropertyType == typeof(int))
						{
							value = condition.Value<int>();
						}
						else
						{
							value = condition.Value<double>();
						}

						break;
					case FilterType.String:
						value = condition.Value<string>();
						break;
					default:
						throw new ArgumentOutOfRangeException();
				}

				//-------------------------------------------------------------------------
				// Aqui removemos todos os registros que não satisfazem a condição
				//-------------------------------------------------------------------------
				data.RemoveAll(
					item =>
					{
						object oValue = item.GetType().GetProperty(field).GetValue(item, null);
						IComparable cItem = oValue as IComparable;

						switch(comparison)
						{
							case Comparison.Eq:

								switch(type)
								{
									case FilterType.List:
										return !(value as List<string>).Contains(oValue.ToString());
									case FilterType.String:
										return !oValue.ToString().ToLower().Contains(value.ToString().ToLower());
									default:
										return !cItem.Equals(value);
								}

							case Comparison.Gt:
								return cItem.CompareTo(value) < 1;
							case Comparison.Lt:
								return cItem.CompareTo(value) > -1;
							default:
								throw new ArgumentOutOfRangeException();
						}
					}
				);
			}

		}
		#endregion

		#region Ordenar
		//-------------------------------------------------------------------------
		// Ordena os registros de acordo com o que foi passado pelo usuário
		//-------------------------------------------------------------------------
		if(!string.IsNullOrEmpty(sort))
		{
			data.Sort(delegate(T x, T y)
			{
				object a;
				object b;

				int direction = dir == "DESC" ? -1 : 1;

				a = x.GetType().GetProperty(sort).GetValue(x, null);
				b = y.GetType().GetProperty(sort).GetValue(y, null);

				return CaseInsensitiveComparer.Default.Compare(a, b) * direction;
			});
		}
		#endregion

		#region Paginar
		//-------------------------------------------------------------------------
		// Faz a paginação do registro.
		//-------------------------------------------------------------------------
		if((start + limit) > data.Count)
		{
			limit = data.Count - start;
		}

		List<T> rangeData = (start < 0 || limit < 0) ? data : data.GetRange(start, limit);
		#endregion

		//retornar
		return new Paging<T>(rangeData, data.Count);
	}
}

Exemplos de acesso

Classe concreta EmployeeHandler

/// <summary>
/// Summary description for EmployeeHandler
/// </summary>
public class EmployeeHandler: HandlerBase<Employee>
{
}

Classe concreta OrderHandler

/// <summary>
/// Summary description for GridPanelHandler
/// </summary>
public class OrderHandler: HandlerBase<Order>
{
}

Estamos quase lá… Vamos ver agora dois exemplos, uma “Combobox” e uma “GridPanel” acessando os dados por um “proxy” e utilizando um “handler” para tratar os dados.

ASPX Code

<ext:ComboBox ID="ComboBox5" runat="server" FieldLabel="Selecione vários colaboradores"
	DisplayField="FirstName" Width="320" LabelWidth="130" QueryMode="Local" TypeAhead="true"
	MultiSelect="true">
	<Store>
		<ext:Store ID="Store5" runat="server" AutoDataBind="true">
			<Proxy>
				<ext:AjaxProxy Url="../DataHandler/EmployeeHandler.ashx">
					<ActionMethods Read="GET" />
					<Reader>
						<ext:JsonReader Root="data" TotalProperty="total" />
					</Reader>
				</ext:AjaxProxy>
			</Proxy>
			<Model>
				<ext:Model ID="Model5" runat="server">
					<Fields>
						<ext:ModelField Name="EmployeeID" />
						<ext:ModelField Name="FirstName" />
						<ext:ModelField Name="LastName" />
					</Fields>
				</ext:Model>
			</Model>
		</ext:Store>
	</Store>
	<ListConfig>
		<ItemTpl ID="ItemTpl2" runat="server">
			<Html>
				<div class="list-item">
							<h3>ID: {EmployeeID}</h3>
							{FirstName} {LastName}
					</div>
			</Html>
		</ItemTpl>
	</ListConfig>
</ext:ComboBox>

GridPanel

ASPX Code

<head id="Head1" runat="server">
    <title>Tutorial Ext.NET</title>
    <link href="../css/gridpanel.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="../Scripts/GridPanel.js"></script>
</head>
<body>
    <form id="Form1" runat="server">
    <ext:ResourceManager ID="ResourceManager1" runat="server" />
    <ext:Window ID="Window1" runat="server" Collapsible="true" Maximizable="true" Icon="Money"
        Title="Orders List" Width="1300" Height="600" X="50" Y="50" Layout="Fit" Closable="false">
        <Items>
            <ext:GridPanel ID="GridPanel1" runat="server" Title="Employees" Frame="true" Header="false"
                Border="false">
                <Store>
                    <ext:Store ID="Store1" runat="server" PageSize="10">
                        <Proxy>
                            <ext:AjaxProxy Url="../DataHandler/OrderHandler.ashx">
                                <ActionMethods Read="GET" />
                                <Reader>
                                    <ext:JsonReader Root="data" TotalProperty="total" />
                                </Reader>
                            </ext:AjaxProxy>
                        </Proxy>
                        <Model>
                            <ext:Model ID="Model1" runat="server">
                                <Fields>
                                    <ext:ModelField Name="CustomerID" />
                                    <ext:ModelField Name="EmployeeID" />
                                    <ext:ModelField Name="OrderDate" />
                                    <ext:ModelField Name="RequiredDate" />
                                    <ext:ModelField Name="ShippedDate" />
                                    <ext:ModelField Name="ShipVia" />
                                    <ext:ModelField Name="Freight" />
                                    <ext:ModelField Name="ShipName" />
                                    <ext:ModelField Name="ShipAddress" />
                                    <ext:ModelField Name="ShipCity" />
                                    <ext:ModelField Name="ShipRegion" />
                                    <ext:ModelField Name="ShipPostalCode" />
                                    <ext:ModelField Name="ShipCountry" />
                                </Fields>
                            </ext:Model>
                        </Model>
                        <Sorters>
                            <ext:DataSorter Property="CustomerID" Direction="ASC" />
                        </Sorters>
                    </ext:Store>
                </Store>
                <ColumnModel ID="ColumnModel1" runat="server">
                    <Columns>
                        <ext:Column ID="Column0" runat="server" Text="CustomerID" Width="150" DataIndex="CustomerID">
                        </ext:Column>
                        <ext:Column ID="Column1" runat="server" DataIndex="EmployeeID" Text="EmployeeID"
                            Width="150" />
                        <ext:DateColumn ID="Column2" runat="server" DataIndex="OrderDate" Text="Order Date"
                            Width="150" Format="dd/MM/yyyy" />
                        <ext:DateColumn ID="DateColumn1" runat="server" DataIndex="RequiredDate" Text="Required Date"
                            Width="110" Format="dd/MM/yyyy" />
                        <ext:DateColumn ID="DateColumn2" runat="server" DataIndex="ShippedDate" Text="Shipped Date"
                            Width="110" Format="dd/MM/yyyy" />
                        <ext:Column ID="Column3" runat="server" DataIndex="ShipVia" Text="Ship Via" Width="150" />
                        <ext:Column ID="Column4" runat="server" DataIndex="Freight" Text="Freight" Width="100" />
                    </Columns>
                </ColumnModel>
                <View>
                    <ext:GridView ID="GridView1" runat="server">
                        <GetRowClass Handler="return 'x-grid-row-expanded';" />
                    </ext:GridView>
                </View>
                <SelectionModel>
                    <ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" />
                </SelectionModel>
                <Features>
                    <ext:RowBody ID="RowBody1" runat="server">
                        <GetAdditionalData Handler="orig.rowBody = '<div><span style=\'color: red\'>Ship Information</span>' + '</br/>' + data.ShipName + '</br/>' + data.ShipAddress + '</br/>' + data.ShipCity + (data.ShipRegion == null ? '' : ' - ' + data.ShipRegion) + '</br/>' + (data.ShipPostalCode == null ? '' : data.ShipPostalCode + '</br/>') + data.ShipCountry + '</div>'; orig.rowBodyColspan = record.fields.getCount();" />
                    </ext:RowBody>
                </Features>
                <BottomBar>
                    <ext:PagingToolbar ID="PagingToolbar1" runat="server">
                        <Items>
                            <ext:Label ID="Label1" runat="server" Text="Page size:" />
                            <ext:ToolbarSpacer ID="ToolbarSpacer1" runat="server" Width="10" />
                            <ext:ComboBox ID="ComboBox1" runat="server" Width="80">
                                <Items>
                                    <ext:ListItem Text="1" />
                                    <ext:ListItem Text="2" />
                                    <ext:ListItem Text="10" />
                                    <ext:ListItem Text="20" />
                                    <ext:ListItem Text="40" />
                                    <ext:ListItem Text="100" />
                                </Items>
                                <SelectedItems>
                                    <ext:ListItem Value="10" />
                                </SelectedItems>
                                <Listeners>
                                    <Select Handler="#{GridPanel1}.store.pageSize = parseInt(this.getValue(), 10); #{GridPanel1}.store.reload();" />
                                </Listeners>
                            </ext:ComboBox>
                        </Items>
                        <Plugins>
                            <ext:ProgressBarPager ID="ProgressBarPager1" runat="server" />
                        </Plugins>
                    </ext:PagingToolbar>
                </BottomBar>
                <Features>
                    <ext:GridFilters ID="GridFilters1" runat="server">
                        <Filters>
                            <ext:StringFilter DataIndex="CustomerID" />
                            <ext:NumericFilter DataIndex="EmployeeID" />
                            <ext:DateFilter DataIndex="OrderDate">
                                <DatePickerOptions runat="server" TodayText="Now" />
                            </ext:DateFilter>
                            <ext:DateFilter DataIndex="RequiredDate">
                                <DatePickerOptions runat="server" TodayText="Now" />
                            </ext:DateFilter>
                            <ext:DateFilter DataIndex="ShippedDate">
                                <DatePickerOptions runat="server" TodayText="Now" />
                            </ext:DateFilter>
                            <ext:NumericFilter DataIndex="ShipVia" />
                            <ext:NumericFilter DataIndex="Freight" />
                        </Filters>
                    </ext:GridFilters>
                </Features>
            </ext:GridPanel>
        </Items>
    </ext:Window>
    </form>
</body>
</html>

Vejam nos códigos em destaque a definição do proxy, vamos agora explicar o que é cada propriedade que foi utilizada.

  • <Proxy>“: Usamos esta marcação para definir que neste “Store” será usado um “proxy“.
  • <ext:AjaxProxy Url=”../DataHandler/OrderHandler.ashx”>“: Esta marcação define o tipo de “proxy” que iremos usar. Eu utilizo, na maioria das vezes, o “AjaxProxy“, sempre me atendeu. Na definição desta marcação temos a propriedade  “Url” e como podem ver, ela define o caminho do nosso “handler” em relação à página;
  • <ActionMethods Read=”GET” />“: Aqui definimos a ação da requisição como um “GET“, pois vamos solicitar uma informação;
  • <ext:JsonReader Root=”data” TotalProperty=”total” />“: Nesta marcação, definimos o nosso “Reader“, nosso leitor da informação, como eu defini que meu retorno no “handler” será um “JSON” .
    • Lembram da definição do “handler“? context.Response.ContentType = “application/json;

    • Esta marcação tem duas propriedades importantes:
      • Root“, que define o nome da marcação pai de todas, no objeto “JSON” retornado e;
      • TotalProperty“, que define o nome da propriedade que representa o total de registros retornados pela aplicação. Veja abaixo um retorno para facilitar o entendimento destas duas propriedades
        {
         "data": [{
         "ID": 1,
         "EmployeeID": 1,
         "LastName": "Davolio",
         "FirstName": "Nancy",
         "Title": "Sales Representative",
         "TitleOfCourtesy": "Ms.",
         "BirthDate": "1948-12-08T00:00:00",
         "HireDate": "1992-05-01T00:00:00",
         "Address": "507 - 20th Ave. E.Apt. 2A",
         "City": "Seattle",
         "Region": "WA",
         "PostalCode": "98122",
         "Country": "USA",
         "HomePhone": "(206) 555-9857",
         "Extension": "5467",
         "Photo": "System.Byte[]",
         "Notes": "Education includes a BA in psychology from Colorado State University in 1970. 
                   She also completed \"The Art of the Cold Call.\" 
                   Nancy is a member of Toastmasters International.",
         "ReportsTo": 2,
         "PhotoPath": "http://accweb/emmployees/davolio.bmp",
         "New": false
         }],
         "total": 1
        }
whew Ufa! Este tópico foi demorado, mas valeu a pena. Aprendemos nele como acessar dados utilizando “Store“, ‘Models“… Definimos “DataSources“, “Proxies” entre outras funcionalidades.E ainda de quebra conhecemos dois componentes, “ComboBox” e “GridPanel“.

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Criando métodos no lado Cliente/Servidor (DirectMethod)

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
18 de junho de 2014

DirectMethod

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

Criando métodos no lado Cliente/Servidor (DirectMethod)

Como vimos, os DirectEvents são extremamente poderosos, são inseridos no controle, lançados no lado cliente e executados no lado servidor.

Com todo este poder de trabalhar do lado cliente integrando ao lado servidor, temos os “DirectMethods“.

note-taking Logo, podemos definir que “DirectMethods” são métodos em .NET definidos no servidor que podemos chama-los no lado cliente pelo javascript.

Vejamos dois exemplos:

Chamando pelo Handler

ASPX Code

<ext:Button ID="Button1" runat="server" Text="Que horas são?" Icon="Clock">
	<Listeners>
		<Click Handler="App.direct.ShowServerTime();">
		</Click>
	</Listeners>
</ext:Button>

Code Behind

[DirectMethod]
public void ShowServerTime()
{
	X.MessageBox.Show(new MessageBoxConfig
	{
		Buttons = MessageBox.Button.OK,
		Title = "Server Time",
		Message = "No servidor são exatamente " + DateTime.Now.ToLongTimeString(),
		Icon = MessageBox.Icon.INFO
	});
}

Chamando pelo ponteiro (Fn)

ASPX Code

<script type="text/javascript" src="../Scripts/DirectMethods.js"></script>
<ext:Button ID="Button2" runat="server" Text="Que horas são?" Icon="Clock">
	<Listeners>
		<Click Fn="MyApp.showTime">
		</Click>
	</Listeners>
</ext:Button>

Crie um arquivo javascript e cole seguinte código no seu arquivo:

/**
<pre> Arquivo de definição dos objetos em javascript
 */

// definir o namespace de base para a aplicação
var MyApp = {};

MyApp.showTime = function() {
    App.direct.ShowServerTime();
};

Vamos analisar agora os pontos importantes do código que foi montado.
Primeiro vamos pegar a definição do método “public void ShowServerTime()” nele temos a definição do atributo  “[DirectMethod]“.

O atributo “DirectMethod” diz ao Ext.NET para criar um proxy entre o cliente e o servidor, automaticamente será criado um código javascript e o nosso método será exposto como um método  javascript.

note-taking Os métodos do tipo “DirectMethod“, diferentes dos tipos ASPX, não precisam ser estáticos, podem ser definidos como não-estáticos e no escopo do objeto.
Se definidos de forma estática, a vantagem é que o ciclo de vida da página ASP não ocorre, mas, em contrapartida, você não pode acessar os controles.

O namespace padrão criado para separar os “DirectMethods” no Ext.NET é o “App.direct“, neste namespace estão todos os “DirectMethods” criados para a requisição. Como pode ser visto na linha em destaque no código javascript.

Perceba que nos dois exemplos, temos a chamada pelo manipulador, “handler” e pela função “Fn“. Ambos já foram explicados no tópico “Utilizando Listeners (Eventos no lado cliente) e DirectEvents (Lado Servidor)“.

Retornando valores

Muitas vezes precisamos ir ao servidor e retornar algum resultado para o lado cliente, isso é possível, pois podemos ter retornos em nossos “DirectMethods“. Vamos aos exemplos:

Com um resultado simples

ASPX Code

<script type="text/javascript" src="../Scripts/DirectMethods.js"></script>
<ext:Button ID="Button3" runat="server" Text="Que horas são?" Icon="Clock">
	<Listeners>
		<Click Fn="MyApp.showTimeResult">
		</Click>
	</Listeners>
</ext:Button>

Code Behind

[DirectMethod]
public string ShowTimeResult()
{
	return "No servidor são exatamente " + DateTime.Now.ToLongTimeString();
}

javascript

MyApp.showTimeResult = function() {
    App.direct.ShowTimeResult({
        success : function(result) {
            Ext.Msg.show({
                title : 'Server Time',
                msg : result,
                buttons : Ext.Msg.OK,
                icon : Ext.Msg.WARNING
            });
        }
    });
};

O retorno não se restringe à apenas os tipos primários, podemos ter o nosso próprio tipo para retornar. Veja o exemplo:

Com um tipo definido

Definindo o nosso tipo

public struct MyInfo
{
	public string Nome { get; set; }
	public string Email { get; set; }
}

ASPX Code

<script type="text/javascript" src="../Scripts/DirectMethods.js"></script>
<ext:Button ID="Button4" runat="server" Text="Quem é você?" Icon="Information">
	<Listeners>
		<Click Fn="MyApp.getInfo">
		</Click>
	</Listeners>
</ext:Button>

Code Behind

[DirectMethod]
public MyInfo GetInfo()
{
	return new MyInfo {
		Nome = "http://desenvolvedores.net",
		Email="aha@evitandospam.com :)"
	};
}

javascript

MyApp.getInfo = function() {
    App.direct.GetInfo({
        success : function(result) {
            var msg = 'Eu sou o site ' + result.Nome + ' e meu e-mail é ' + result.Email;

            Ext.Msg.show({
                title : 'Info',
                msg : msg,
                buttons : Ext.Msg.OK,
                icon : Ext.Msg.INFO
            });
        }
    });
};

DirectMethods com parâmetros

Tipos primitivos

Podemos passar parâmetros para os nossos “DirectMethods“. No exemplo abaixo, eu vou utilizar um parâmetro do tipo data, calcular a idade e retornar a idade que deverá ser exibida ao utilizador da aplicação.

ASPX Code

<ext:DateField ID="DateField1" runat="server" FieldLabel="Data de Nascimento">
</ext:DateField>
<script type="text/javascript" src="../Scripts/DirectMethods.js"></script>
<ext:Button ID="Button5" runat="server" Text="Qual a sua idade?" Icon="Information">
	<Listeners>
		<Click Handler="MyApp.getAge(#{DateField1}.value);">
		</Click>
	</Listeners>
</ext:Button>
note-taking Atenção à linha em destaque, como utilizamos a passagem de parâmetro direto pelo evento, temos que definir a chamada como um “handler” , pois caso contrário o nosso método será chamado durante o carregamento da página. E não queremos isso. 🙂

Code Behind

[DirectMethod]
public int GetAge(DateTime dob)
{
	int age = DateTime.Now.Year - dob.Year;
	if(DateTime.Now.Month < dob.Month ||
		(DateTime.Now.Month == dob.Month &&
		DateTime.Now.Day < dob.Day))
		age--;

	return age;
}

javascript

MyApp.getAge = function(dob) {
    App.direct.GetAge(dob, {
        success : function(result) {
            var msg = 'Olá! Você tem ' + result + ' anos.';

            Ext.Msg.show({
                title : 'Age',
                msg : msg,
                buttons : Ext.Msg.OK,
                icon : Ext.Msg.INFO
            });
        }
    });
};

Parâmetros com tipos definidos

Se existir a necessidade de se passar um tipo definido como parâmetro, isso também é possível. Veja o exemplo:

ASPX Code

<ext:TextField ID="TextField1" runat="server" FieldLabel="Informe seu nome">
</ext:TextField>
<ext:TextField ID="TextField2" runat="server" FieldLabel="Informe seu email">
</ext:TextField>
<ext:Button ID="Button6" runat="server" Icon="Accept" Text="Enviar">
	<Listeners>
		<Click Handler="MyApp.showInfo(#{TextField1}.value, #{TextField2}.value);">
		</Click>
	</Listeners>
</ext:Button>

Code Behind

[DirectMethod]
public string ShowInfo(MyInfo info)
{
	return String.Format("Olá {0}! Seu e-mail é {1}.", info.Nome, info.Email);
}

javascript

MyApp.showInfo = function(nome, email) {
    /*
     * Devemos criar aqui o nosso objeto que será passado como parâmetro.
     * Temos que respoeitar exatamente a definição de nome que demos à nossas
     * propriedades.
     * Os nomes das propriedades do objeto criado não são sensíveis ao caso.
     */
    var myinfo = {
        nome : nome,
        email : email
    };

    App.direct.ShowInfo(myinfo, {
        success : function(result) {
            Ext.Msg.show({
                title : 'Info',
                msg : result,
                buttons : Ext.Msg.OK,
                icon : Ext.Msg.INFO
            });
        }
    });
};

Tratando exceções

Como nossos sitema não é a prova de falhas, temos que tratar as exceções que podem ocorrer no processamento de uma requisição ao servidor.
Nos exemplos abaixo, iremos ver as exceções tratadas e as não tratadas.

Uma exceção tratada

ASPX Code

<ext:Button ID="Button7" runat="server" Icon="Error" Text="Erro :(">
	<Listeners>
		<Click Fn="MyApp.catchException">
		</Click>
	</Listeners>
</ext:Button>

Code Behind

[DirectMethod]
public void CatchException()
{
	try
	{
		throw new Exception("Ops! Um erro foi lançado.");
	}
	catch(Exception ex)
	{
		Ext.Net.ResourceManager.AjaxSuccess = false;
		Ext.Net.ResourceManager.AjaxErrorMessage = ex.Message;
	}
}
note-taking As duas linhas em destaque indicam que o retorno deverá acontecer como uma falha, logo devemos dizer ao Ext.NET que houve um erro na requisição. Para isso passamos a propriedade “Ext.Net.ResourceManager.AjaxSuccess” para false e a propriedade “Ext.Net.ResourceManager.AjaxErrorMessage” irá receber a mensagem de erro que será exibida ao utilizador da aplicação.

javascript

MyApp.catchException = function() {
    App.direct.CatchException({
        failure : function(result) {
            Ext.Msg.alert('Erro!', result);
        }
    });
};
note-taking Neste ponto, temos que tratar um método diferente,no caso o método “failure‘ que será chamado sempre que ocorrer um erro no lado servidor, ou sempre que a propriedade “Ext.Net.ResourceManager.AjaxSuccess” retornar “false“.

Uma exceção não tratada

ASPX Code

<ext:Button ID="Button8" runat="server" Icon="Error" Text="Erro não tratado :(">
	<Listeners>
		<Click Fn="MyApp.unhandledException">
		</Click>
	</Listeners>
</ext:Button>

Code Behind

[DirectMethod]
public void UnhandledException()
{
	throw new Exception("Ops! Um erro não tratado foi lançado.");
}

javascript

MyApp.unhandledException = function() {
App.direct.UnhandledException({
	failure : function(result) {
		Ext.Msg.alert('Erro!', result);
	}
});
}; 

Uma exceção não tratada e sem “failure”

<ext:Button ID="Button9" runat="server" Icon="Error" Text="Erro não tratado e sem failure :(">
	<Listeners>
		<Click Handler="App.direct.UnhandledException();">
		</Click>
	</Listeners>
</ext:Button>

Como podemos perceber, é sempre bom termos o hábito de tratar a falha em uma requisição “DirectMethod“, nunca sabemos se ela irá acontecer ou não devido aos diversos fatores quando desenvolvemos para web.

Se o método “failure” não for especificado, uma caixa de mensagem semelhante à esta será exibida.

request_failure

Mais sobre “DirectMethods”

Como vimos, o namespace padrão definido pelo Ext.NET é o “App.direct”, mas, podemos decidir que queremos utilizar o nosso próprio namespace, para isso temos que modificar a definição do nosso atributo “[DirectMethod]“, vejamos algumas propriedades do mesmo.

Definindo um namespace (CompanyX)

ASPX Code

<ext:Button ID="Button10" runat="server" Icon="ApplicationGo" Text="Namespace Defin">
	<Listeners>
		<Click Fn="MyApp.definedNamespace">
		</Click>
	</Listeners>
</ext:Button>

Code Behind

[DirectMethod(Namespace = "CompanyX")]
public void DefinedNamespace()
{
	X.MessageBox.Show(new MessageBoxConfig
	{
		Buttons = MessageBox.Button.OK,
		Title = "Olá!",
		Message = "Eu fui chamado de um namespace definido por você. :)",
		Icon = MessageBox.Icon.INFO
	});
}
note-taking Perceba que na linha em destaque, nós adicionamos o namespace que queremos para a nossa aplicação, neste caso “CompanyX

javascript

MyApp.definedNamespace = function() {
    CompanyX.DefinedNamespace();
};
question Isto é útil quando temos uma aplicação muito grande, e queremos definir o nosso próprio namespace.
Mas, eu tenho que ficar a todo momento definindo o namespace para um “DirectMethod“?

R: Não.
Você não precisa a todo momento ficar escrevendo o namespace padrão.
Dentro do web.config, nas configurações do ext.net você pode adicionar a seguinte propriedade

<extnet directMethodNamespace="CompanyX"/>

e voilà todos os seus “DirectMethods” estarão utilizando o namespace padrão “CompanyX“.

 

note-taking Mas tome o cuidado de corrigir todos os pontos que você usou o namespace antigo “App.direct“, pois eles deixarão de funcionar.

Para saber mais sobre “DirectMethods” veja os exemplo em http://examples.ext.net/#/Events/DirectMethods/Overview/


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Listeners_Eventos

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

Listeners – Eventos lado cliente

Para facilitar o entendimento do artigo, vamos primeiro definir o que são listeners e eventos.

Listeners

Listeners são objetos ouvintes que notificam outros objetos quando acontece alguma mudança no comportamento do objeto. Os listeners utilizam o Design Pattern Observer.

Eventos

Os eventos são os tipos mais comuns que utilizam um listener, pois são neles que definimos quais métodos  serão chamados (Alguém disse delegates?) quando uma ação ocorrer.

Eventos são lançados sempre que uma ação acontece no nosso objeto, seja motivada pelo usuário, pelo próprio sistema ou por mensagens do sistema operacional.

Eventos no Ext.NET

O Ext.NET suporta eventos do lado cliente, AJAX e as formas tradicionais de tratamento de eventos.
Cada componente tem seus eventos, lado cliente, definidos dentro da tag “listeners“.

Como exemplo, vamos pegar um simples clique de botão e exibir uma mensagem.

<body>
    <ext:ResourceManager ID="ResourceManager1" runat="server">
    </ext:ResourceManager>
    <form id="form1" runat="server">
    <ext:Button ID="Button1" runat="server" Icon="Accept" Text="Clica em mim.">
        <Listeners>
            <Click Handler="Ext.Msg.show({
                                                   title: 'Oi!',
                                                   msg: 'Oba! Fui clicado.',
                                                   buttons: Ext.Msg.OK,
                                                   icon: Ext.Msg.WARNING
                                               });">
            </Click>
        </Listeners>
    </ext:Button>
    </form>
</body>

Neste pequeno trecho de código podemos dizer que tratamos o evento clique de um botão qualquer.

Uma outra forma de tratarmos o evento, seria criando uma função em javascript.

note-taking Eu, particularmente, prefiro esta segunda abordagem, pois assim deixo todos os meus fontes separados entre as classes (.cs), o código html (.aspx) e o código de script (.js).

Para este exemplo, crie um arquivo com o nome de “MyApp.js” no seu projeto e cole o código abaixo:

/**
 Arquivo de definição dos objetos em javascript
 */

// definir o namespace de base para a aplicação
var MyApp = {};

/**
 Define o método listener para o clique do botão
 */
MyApp.Button1Click = function() {
    Ext.Msg.show({
        title : 'Oi!',
        msg : 'Oba! Fui clicado em uma função.',
        buttons : Ext.Msg.OK,
        icon : Ext.Msg.WARNING
    });
};

Agora para a chamada do método clique, iremos definir um ponteiro para uma função em javascript.

<ext:Button ID="Button2" runat="server" Icon="Accept" Text="Clica em mim.">
        <Listeners>
            <Click Fn="MyApp.Button1Click">
            </Click>
        </Listeners>
</ext:Button>

Neste ponto podemos perceber que temos dois meios de chamar um método para o evento “Click“, no primeiro utilizamos um manipulador (handler) diretamente na definição do evento. E no segundo método, definimos um ponteiro (pointer) para uma função definida em nosso arquivo de script.

Esta é a diferença entre usar “Handler” e “Fn“.

Se o evento só deve ser executado uma única vez, podemos definir a propriedade “Single” para “true” e o evento só será executado uma vez, até que a página seja recarregada.

Se for necessário definir o escopo em que o evento deverá ser executado, devemos utilizar a propriedade “scope” e passar o nome do objeto contêiner onde o evento será executado. Se nada for informado, será utilizado o escopo global.

Determinando os argumentos do evento

Usando a documentação do Ext JS você poderá encontrar os argumentos que são passados para cada evento. Tenha em mente que diferentes controles têm diferentes eventos e assinaturas de evento.

Para uma documentação completa do lado cliente veja o link http://docs-origin.sencha.com/extjs/4.1.3.

DirectEvents (Eventos do Lado Servidor)

Os “DirectEvents” são eventos que são lançados pelo lado cliente e que podem ser capturados pelo lado servidor.

Tenha em mente que quando um “DirectEvent” é lançado, todo o controle deverá ser reconstruído do lado servidor, como é feito em um post tradicional. Se o seu form tem o atributo “runat=’server’” todo o formulário será reenviado por padrão.

Isto pode nos causar alguns problemas e para validar se devemos recriar e evitar vários códigos de inicialização da nossa página, podemos usar a propriedade “X.IsAjaxRequest”,  se true, a requisição veio de um evento AJAX.  Esta propriedade funciona como a propriedade do ASP.NET “IsPostBack“.

Vamos ver 3 exemplos de chamadas “DirectEvents” que são usados com muito frequência.

Sem parâmetros

ASPX Code

<ext:Button ID="Button1" runat="server" Icon="Clock" Text="Que horas são?"><DirectEvents>
            <Click OnEvent="Button1Click">
            </Click>
        </DirectEvents>
    </ext:Button>

Code Behind

protected void Button1Click(object sender, DirectEventArgs e)
        {
            X.Msg.Show(new MessageBoxConfig
            {
                Buttons = MessageBox.Button.OK,
                Title = "Olá!",
                Message = String.Format("São {0}.", DateTime.Now.ToLongTimeString())
            });
        }

Com parâmetros

Para definir parâmetros, temos que utilizar a marcação “ExtraParams” que possuem 3 propriedades importantes:

  1. Mode:
    1. Pode ser “Raw“: Define que o conteúdo da propriedade  “Value” deverá ser executado antes de ser enviado ao servidor;
    2. Poder ser “Value“: Define que o conteúdo da propriedade “Value” deverá ser retornado como especificado;
  2. Name: Nome do parâmetro que será enviado ao servidor, pode ser passado mais de um item de parâmetro, este nome será o índice que iremos recuperar o valor do parâmetro no servidor;
  3. Value:  Valor que deverá ser passado ao servidor, atente para o item 1. Mode, que define como este valor deverá ser interpretado;

ASPX Code

<ext:TextField ID="TextField1" runat="server" FieldLabel="Informe seu nome.">
    </ext:TextField>
    <ext:Button ID="Button2" runat="server" Icon="Clock" Text="Que horas são?">
        <DirectEvents>
            <Click OnEvent="Button2Click">
                <ExtraParams>
                    <ext:Parameter Mode="Raw" Value="#{TextField1}.value" Name="nome">
                    </ext:Parameter>
                </ExtraParams>
            </Click>
        </DirectEvents>
    </ext:Button>

Code Behind

protected void Button2Click(object sender, DirectEventArgs e)
        {
            //Perceba que pegamos aqui pelo nome do extra params que informamos no ASPX Code
            string nome = e.ExtraParams["nome"];

            X.Msg.Show(new MessageBoxConfig
            {
                Buttons = MessageBox.Button.OK,
                Title = String.Format("Olá {0}!", nome),
                Message = String.Format("São {0}.", DateTime.Now.ToLongTimeString())
            });
        }

Com parâmetros de um objeto definido

Com esta opção, podemos criar um objeto do lado cliente e passar este objeto para o lado servidor.
Do lado servidor o mesmo deverá ser recriado para um objeto compreendido pelo C#.

Para este exemplo, iremos criar um arquivo de javascript com o nome de  DirectEvent.js com o seguinte código:

/**
 Arquivo de definição dos objetos em javascript
 */

// definir o namespace de base para a aplicação
var MyApp = {};

/**
 Define o método listener para o clique do botão
 */
MyApp.Button3Click = function() {
    //Aqui iremos criar um objeto do tipo 'MyInfo', esperado pelo lado servidor
    var result = {
        Nome : Ext.getCmp('TextField2').value,
        Email : Ext.getCmp('TextField3').value
    };

    return result;
};

ASPX Code

<script type="text/javascript" src="../Scripts/DirectEvent.js"> </script>
    <ext:TextField ID="TextField2" runat="server" FieldLabel="Informe seu nome">
    </ext:TextField>
    <ext:TextField ID="TextField3" runat="server" FieldLabel="Informe seu email">
    </ext:TextField>
    <ext:Button ID="Button3" runat="server" Icon="Clock" Text="Enviar">
        <DirectEvents>
            <Click OnEvent="Button3Click">
                <ExtraParams>
                    <ext:Parameter Mode="Raw" Value="MyApp.Button3Click()" Name="dados">
                    </ext:Parameter>
                </ExtraParams>
            </Click>
        </DirectEvents>
    </ext:Button>

Code Behind

Definição do objeto que o lado cliente deverá retornar

/// <summary>
/// Objeto retornado pelo cliente
/// </summary>
struct MeusDados
{
    public string Nome { get; set; }
    public string Email { get; set; }
}

Método que irá receber a informação do lado cliente e converter para o objeto esperado

protected void Button3Click(object sender, DirectEventArgs e)
{
    // Aqui iremos converter o objeto que recebemos do lado cliente
   // em um objeto do tipo "MyInfo"
    MyInfo dados = JSON.Deserialize<MyInfo>(e.ExtraParams["dados"]);
    X.Msg.Show(new MessageBoxConfig
    {
        Buttons = MessageBox.Button.OK,
        Title = String.Format("Olá {0}!", dados.Nome),
        Message = String.Format("Seu e-mail é  {0}.", dados.Email)
    });
}

Neste tópico não iremos abordar como criar  o nosso próprio manipulador de eventos. Este será abordado no tópico “Criando componentes no lado Servidor


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Definindo leiautes com Ext.Net

1
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
16 de junho de 2014

Leiaute_ComExtNet

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

Definindo leiautes com Ext.NET

As aplicações web precisam de leiautes ricos e sofisticados, para isto, o Ext.NET provê um conjunto de componentes para se trabalhar com leiautes.

Neste tópico, iremos falar sobre:

  • Viewport: Onde você pode dizer à página  web para trabalhar como uma aplicação;
  • Os mais comuns, como Border, Accordion, Anchor  entre outros;
  • Maneiras diferentes de se trabalhar com leiaute , no markup, no código, nas propriedades, etc.;

Viewport

O viewport não é um leiaute , ele está mais para um contâiner especial que exibe toda a área disponível do navegador e fica sempre no primeiro nível da página, sobre todos os outros componentes, ele se redimensiona quando a janela do navegador é redimensionada. Mas, só podemos ter um viewport por página.

O viewport pode redimensionar todos os seus componentes, que pode ser qualquer um, normalmente são painéis ou suas subclasses, desta forma o viewport se torna o mais fácil para se trabalhar com leiautes responsivos.

No viewport você pode definir qual o tipo de leiaute que deseja trabalhar.

 Border

O tipo permite que tenhamos uma divisão da página em 5 regiões:

  • Norte (North): Temos que definir obrigatoriamente a altura;
  • Sul (South): Temos que definir obrigatoriamente a altura;
  • Leste (East): Temos que definir obrigatoriamente a largura;
  • Oeste (Wets): Temos que definir obrigatoriamente a largura;
  • Centro (center): A região central é a única que é obrigatória existir. Ela não precisa ter tamanho definido, irá preencher todo o espaço disponível na tela

Em cada região, podemos ter qualquer componente, mas o mais comum é usar um painel, ou suas subclasses.

Não podemos usar um componente Window, se a nossa intenção for que esta janela seja flutuante.

Abaixo um exemplo do Viewport usando o leiaute do tipo Border.

<body>
 <ext:ResourceManager runat="server">
 </ext:ResourceManager>
 <form id="form1" runat="server">
 <ext:Viewport ID="Viewport1" runat="server" Layout="BorderLayout">
 <Items>
 <ext:Panel ID="Panel1" runat="server" Title="Norte" Region="North" Split="true" Height="150"
 BodyPadding="6" Html="Norte" Collapsible="true" />
 <ext:Panel ID="Panel2" runat="server" Title="Oeste" Region="West" Layout="AccordionLayout"
 Width="225" MinWidth="225" MaxWidth="400" Split="true" Collapsible="true">
 <Items>
 <ext:Panel ID="Panel3" runat="server" Title="Navegação" Border="false" BodyPadding="6"
 Icon="FolderGo" Html="Oeste" />
 <ext:Panel ID="Panel4" runat="server" Title="Configuração" Border="false" BodyPadding="6"
 Icon="FolderWrench" Html="As configurações vão aqui ... " />
 </Items>
 </ext:Panel>
 <ext:TabPanel ID="TabPanel1" runat="server" Region="Center">
 <Items>
 <ext:Panel ID="Panel5" runat="server" Title="Centro" Border="false" BodyPadding="6"
 Html="<h1>Exemplo com BorderLayout</h1>" />
 <ext:Panel ID="Panel6" runat="server" Title="Fechar" Closable="true" Border="false"
 BodyPadding="6" Html="Eu posso ser fechada" />
 </Items>
 </ext:TabPanel>
 <ext:Panel ID="Panel7" runat="server" Title="Leste" Region="East" Collapsible="true"
 Split="true" MinWidth="225" Width="225" Layout="Fit">
 <Items>
 <ext:TabPanel ID="TabPanel2" runat="server" ActiveTabIndex="1" TabPosition="Bottom"
 Border="false">
 <Items>
 <ext:Panel ID="Panel8" runat="server" Title="Tab 1" Border="false" BodyPadding="6"
 Html="Primeira Aba" />
 <ext:Panel ID="Panel9" runat="server" Title="Tab 2" Closable="true" Border="false"
 BodyPadding="6" Html="Segunda Aba" />
 </Items>
 </ext:TabPanel>
 </Items>
 </ext:Panel>
 <ext:Panel ID="Panel10" runat="server" Title="Sul" Region="South" Split="true"
 Collapsible="true" Height="150" BodyPadding="6" Html="Sul" />
 </Items>
 </ext:Viewport>
 </form>
</body>

Como podemos ver, as regiões podem ser configuradas para serem redimensionadas, divididas ao gosto do freguês e não se restringem a apenas painéis, como podemos ver no exemplo abaixo usando abas.

<body>
<form id="form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server">
</ext:ResourceManager>
<ext:Window ID="Window1" runat="server" Title="Com bordas" Layout="BorderLayout"
Height="480" Width="640">
<Items>
<ext:Panel ID="Panel1" runat="server" Title="Oeste" Region="West" Width="100">
</ext:Panel>
<ext:TabPanel ID="TabPanel1" runat="server" Region="Center">
<Items>
<ext:Panel ID="Panel2" runat="server" Title="Primeira Aba">
</ext:Panel>
<ext:Panel ID="Panel3" runat="server" Title="Segunda Aba">
</ext:Panel>
</Items>
</ext:TabPanel>
</Items>
</ext:Window>
</form>
</body>

Absolute

O leiaute do tipo “Absolute” define um leiaute onde podemos informar as coordenadas X,Y de um componente.

<body>
 <ext:ResourceManager runat="server">
 </ext:ResourceManager>
 <form id="form1" runat="server">
 <ext:Window ID="Window1" runat="server" Height="480" Width="640" Layout="Absolute"
 Title="Cadastro" Icon="ApplicationForm">
 <Items>
 <ext:TextField ID="TextField1" runat="server" FieldLabel="Nome" X="130" Y="0">
 </ext:TextField>
 <ext:TextField ID="TextField2" runat="server" FieldLabel="Telefone" X="130" Y="25">
 </ext:TextField>
 <ext:TextField ID="TextField3" runat="server" FieldLabel="Email" X="130" Y="50">
 </ext:TextField>
 <ext:Image ID="Image1" runat="server" Height="128" Width="128" ShrinkWrap="Both"
 X="0" Y="0" ImageUrl="Resources/eu.jpg">
 </ext:Image>
 </Items>
 </ext:Window>
 </form>
</body>

Anchor

O leiaute do tipo âncora define em porcentagem o quanto componente pode usar do espaço disponível e automaticamente redimensiona o mesmo se o navegador redimensionar a tela.

<body>
    <ext:ResourceManager ID="ResourceManager1" runat="server">
    </ext:ResourceManager>
    <form id="form1" runat="server">
    <ext:Window ID="Window1" runat="server" Height="480" Width="640" Layout="Absolute"
        Title="Cadastro" Icon="ApplicationForm">
        <Items>
            <ext:Container runat="server" Layout="Absolute" X="0" Y="0">
                <Items>
                    <ext:Image ID="Image1" runat="server" Height="128" Width="128" X="0" Y="0" ImageUrl="Resources/eu.jpg">
                    </ext:Image>
                </Items>
            </ext:Container>
            <ext:Container runat="server" Layout="Absolute" X="130" Y="0" Frame="true" Border="false">
                <Items>
                    <ext:TextField ID="TextField1" runat="server" FieldLabel="Nome" X="0" Y="0" Anchor="100%">
                    </ext:TextField>
                    <ext:TextField ID="TextField2" runat="server" FieldLabel="Telefone" X="0" Y="25"
                        AnchorHorizontal="100%">
                    </ext:TextField>
                    <ext:TextField ID="TextField3" runat="server" FieldLabel="Email" X="0" Y="50" AnchorHorizontal="100%">
                    </ext:TextField>
                </Items>
            </ext:Container>
        </Items>
    </ext:Window>
    </form>
</body>

Outros layouts

O Ext.NET oferece muitos outros leiautes e seria além do escopo deste artigo descrever todos.
Os leiautes acima, foram apenas exemplos que são amplamente utilizados e cobrem a maior parte da técnica para os demais.

Mas aqui está uma breve lista de outros layouts:

  • Card: Empilha componentes em cima uns dos outros. É o desenvolvedor que tem a Responsabilidade para ocultar ou mostrar o componente certo em tempo de programação.
    O “TabPanel” é uma extensão desta ideia, escondendo guias específicas, conforme necessário.
  • Column: Suporta várias colunas dento de uma página ou componente de leiaute;
  • Form: É uma simples forma de exibir cada componente, um em cima do outro, mas de uma forma que vai esticar a largura do componente quando redimensionado;
  • Table: Um leiaute de tabela, como o nome já diz, trabalha exatamente como uma tabela, suporta “spanning” de linhas e colunas;
note-taking Eu tenho por hábito, utilizar o “Card” leiaute para criar assistentes (“Wizards”).

Para conhecer mais sobre leaiutes, veja nos exemplos:

http://examples.ext.net/#/Layout/AbsoluteLayout/Basic/


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Utilizando o componente Window

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
29 de maio de 2014

Windows

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

Windows

Uma janela , é um classe filha da classe  “Panel“.

Podemos utilizar em um sistema desktop para exibir as janelas, elas podem ser redimensionadas, ancoradas, modais, maximizadas, minimizadas, resumindo, podemos fazer com que elas tenham o mesmo comportamento em uma aplicação Desktop tradicional.

Primeira janela

Para criar uma janela, utilizamos a seguinte sintaxe:

<ext:Window ID="Window1" runat="server" Title="Ext.NET by Desenvolvedores.net" Width="390"
 Height="290" Layout="FitLayout">
 <Items>
 <ext:Panel ID="Panel1" runat="server" Border="false" />
 </Items>
 </ext:Window>

Este código irá gerar uma janela simples, de tamanho 390×290, como não passamos a posição inicial será exibida no meio da página.

Chamando por botões

No código abaixo iremos chamar a janela por um botão, será criada em tempo de execução.

<ext:Button ID="Button1" runat="server" Text="Exibir Janela">
 <Listeners>
 <Click Handler="#{Window2}.show();" />
 </Listeners>
 </ext:Button>
 <ext:Window ID="Window2" runat="server" AnimateTarget="Button1" CloseAction="Hide"
 Height="200" Hidden="true" Icon="ApplicationCascade" Maximizable="true" Minimizable="true"
 Modal="true" Title="Minha janela modal" Width="300">
 <Listeners>
 <Minimize Handler="this.hide();" />
 </Listeners>
 </ext:Window>

Explicando algumas propriedades

No exemplo acima utilizamos algumas propriedades que valem a pena uma explicação:

  • AnimateTarget: É o nome (ID) do controle que vai receber a animação da janela, no caso ela vai sumindo sentido ao controle. É apenas para deixar o visual mais bonito, desta forma a janela não simplesmente “aparece” na tela;
  • CloseAction: É a ação que será executada quando a janela for fechada. Os valores possíveis são:
    • Destroy: A janela é destruída e não pode mais se utilizada. Pode ser usado em casos onde a janela deve ser exibida apenas uma vez;
    • Hide: Apenas esconde a janela no navegador. Esta opção permite que a janela possa ser exibida e escondida quantas vezes forem necessárias;
  • Minimizable e Maximizable: Cria os dois ícones de maximizar e minimizar a janela, no canto superior direito;
  • Modal: Exibe uma janela no topo das outras. A página ficará com um cor esmaecida, e só ficará visível a janela modal. Útil para janelas do tipo diálogo, caixas de mensagens, etc.

Chamando em Postback

Se houver a necessidade de um “postback” para depois abrir a janela, também é possível. Para isso temos  que:

  1. Setar a propriedade “AutoPostBack” do botão para “true“;
  2. Criar um método no lado servidor, (Code Behind), que irá chamar a sua janela.

Exemplos:

Code design:

<ext:Window ID="Window3" runat="server" CloseAction="Hide" Height="200" Hidden="true"
 Icon="House" Maximizable="true" Minimizable="true" Title="Minha janela postback"
 Width="300">
 </ext:Window>
<ext:Button ID="Button2" runat="server" Text="Exibir Janela com Postback" OnClick="Button2_Click" AutoPostBack="true"></ext:Button>

Code behind

protected void Button2_Click(object sender, EventArgs e)
 {
        this.Window3.Show();
 }

Caso o seu exemplo de PostBack não funcione, verifique se colocou os componentes dentro da tag:

<form runat="server"></form>

Caso contrário não irá funcionar.

Carregar página.

Podemos usar também o componente de janelas para exibir uma página ao ser exibida. Veja exemplo:

<ext:Window ID="Window4" runat="server" CloseAction="Hide" Height="480" Hidden="true"
 Icon="House" Maximizable="true" Minimizable="true" Title="Site: Desenvolvedores.NET"
 Width="640">
 <Loader runat="server" Url="http://desenvolvedores.net" Mode="Frame">
 <LoadMask Msg="Carregando desenvolvedores.net" ShowMask="true">
 </LoadMask>
 </Loader>
 </ext:Window>
 <ext:Button ID="Button3" runat="server" Text="Carregar site">
 <Listeners>
 <Click Handler="#{Window4}.show();" />
 </Listeners>
 </ext:Button>

Explicando algumas propriedades

  • Loader: Define o que deverá ser carregado no componente.
    • URL: Define a URL que deverá ser carregada no componente.
    • Mode: Define que será carregado como um frame dentro do componente.
  • LoadMask: Define a mensagem que será carregada no componente.
    • ShowMask: Se true a mensagem é exibida, se não, oculta.

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Utilizando os componentes básicos

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
28 de maio de 2014

Componentes_Basicos

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

Ao longo deste tópico conheceremos os componentes, com exemplos de uso simples. Sem nos preocuparmos diretamente com os eventos, que serão explicados no artigo “Utilizando Listeners (Eventos no lado cliente) e DirectEvents (Lado Servidor)“.

Vou assumir que você vem acompanhando o artigo, e já tem a base para seus fontes criada. Desta forma irei postar apenas os exemplos.

Botões

Se você está acostumado com o uso do HTML, você usa a tag <input type=”button”> para criar um simples botão. Isto é útil, quando estamos falando de html.

Mas aplicações em Desktop têm muitas variações para os botões, como SplitButtons, MenuButtons entre outros .

Para isso o Ext.Net tem o próprio componente de botão. Vamos à alguns exemplos:

Com Listener (Iremos ver o que são listeners)

 <ext:Button ID="Button1" runat="server" Text="Clica eu">
 <Listeners>
 <Click Handler="alert('Opa! Fui clicado... ');" />
 </Listeners>
 </ext:Button>

Com DirectEvent (Iremos ver o que é também)

 <ext:Button ID="Button2" runat="server" Text="Clica eu">
 <DirectEvents>
 <Click OnEvent="Button_Click">
 <EventMask ShowMask="true" />
 <ExtraParams>
 <ext:Parameter Name="Item" Value="Fui clicado e respondi pelo server..." />
 </ExtraParams>
 </Click>
 </DirectEvents>
 </ext:Button>

Com ícones

<ext:Button ID="Button3" runat="server" Text="Texto do seu botão" Icon="Add" />

Com Tooltip

<ext:Button ID="Button5" runat="server" Text="Texto do seu botão">
<ToolTips>
<ext:ToolTip ID="ToolTip1" runat="server" Title="Oi! Eu sou um título" Html="Só para não perder o hábito. Olá mundo..." />
</ToolTips>
</ext:Button>

Trocas

<ext:Button ID="Button6" runat="server" Text="Button1" EnableToggle="true" ToggleGroup="Group1"

 Pressed="true" />
 <ext:Button ID="Button7" runat="server" Text="Button2" EnableToggle="true" ToggleGroup="Group1" />
 <ext:Button ID="Button8" runat="server" Text="Button3" EnableToggle="true" ToggleGroup="Group1" />

 Menus

<ext:Button ID="Button9" runat="server" Text="Texto do seu botão">
<Menu>
<ext:Menu ID="Menu1" runat="server">
<Items>
<ext:MenuItem ID="MenuItem1" runat="server" Text="Item 1" Icon="GroupAdd" />
<ext:MenuItem ID="MenuItem2" runat="server" Text="Item 2" Icon="GroupDelete" />
<ext:MenuItem ID="MenuItem3" runat="server" Text="Item 3" Icon="GroupEdit" />
</Items>
</ext:Menu>
</Menu>
</ext:Button>

Divisor com menus

<ext:SplitButton ID="SplitButton1" runat="server" Text="Texto do seu botão">
<Menu>
<ext:Menu ID="Menu2" runat="server">
<Items>
<ext:MenuItem ID="MenuItem4" runat="server" Text="Item 1" Icon="GroupAdd" />
<ext:MenuItem ID="MenuItem5" runat="server" Text="Item 2" Icon="GroupDelete" />
<ext:MenuItem ID="MenuItem6" runat="server" Text="Item 3" Icon="GroupEdit" />
</Items>
</ext:Menu>
</Menu>
</ext:SplitButton>

Botão chato

<ext:Button ID="Button11" runat="server" Text="Eu sou chato" Icon="Accept" Flat="true" />

Para mais exemplos de botões e menus:

Labels

Simples

<ext:Label ID="Label1" runat="server" Text="Olá Mundo ... de novo" />

Com Html

<ext:Label ID="Label2" runat="server" Html="<i>Eu sou um HTML</i>" />

Com ícones

<ext:Label ID="Label3" runat="server" Text="Olá Mundo!" Icon="Accept" />

Ícone a direita

<ext:Label ID="Label4" runat="server" Text="Chega de Olá Mundo." Icon="Accept" IconAlign="Right" />

Campos de texto

Os campos de texto, “TextField”, são muito flexíveis quanto à sua utilização, com eles podemos mascarar valores, temos campos de senha, etc. Iremos ver abaixo várias utilidades para os campos de texto, inputs.

Campos simples

<ext:TextField ID="TextField1" runat="server" FieldLabel="Digite algo:">
    </ext:TextField>

Senhas

<ext:TextField ID="TextField2" runat="server" FieldLabel="Informe a senha">
        <Plugins>
            <ext:PasswordMask ID="PasswordMask1" runat="server">
            </ext:PasswordMask>
        </Plugins>
    </ext:TextField>

Para mais exemplos de senha:

Máscaras

As máscaras servem para formatar os campos do tipo texto. Estas máscaras podem ser usadas para a validação do formulário, bem como para a exibição.

<ext:TextField ID="TextField1" runat="server" FieldLabel="Telefone">
        <Plugins>
            <ext:InputMask ID="InputMask1" runat="server" Mask="(999) 999-9999" />
        </Plugins>
    </ext:TextField>
    <ext:TextField ID="TextField2" runat="server" FieldLabel="CPF">
        <Plugins>
            <ext:InputMask ID="InputMask2" runat="server" Mask="999.999.999-99">
            </ext:InputMask>
        </Plugins>
    </ext:TextField>
    <ext:TextField ID="TextField3" runat="server" FieldLabel="CNPJ">
        <Plugins>
            <ext:InputMask ID="InputMask3" runat="server" Mask="99.999.999/9999-99">
            </ext:InputMask>
        </Plugins>
    </ext:TextField>
    <ext:TextField ID="TextField4" runat="server" FieldLabel="CEP">
        <Plugins>
            <ext:InputMask ID="InputMask4" runat="server" Mask="99999-999">
            </ext:InputMask>
        </Plugins>
    </ext:TextField>

Campos Numéricos

Os campos numéricos herdam da classe “TextField“, eles exibem um ícone de rolagem para facilitar  aos usuários informarem o valor.

Estes campos só permitem que sejam digitados números.

<ext:NumberField ID="NumberField1" runat="server" FieldLabel="Digite um número" MinValue="0"
 MaxValue="100" AllowDecimals="true" DecimalPrecision="1" Step="0.5" Number="3" />

No nosso exemplo temos o valor inicial setado como 3, devido a propriedade “Number“. Podemos também definir um limite para os números que são digitados usando as propriedades “MinValue” e “MaxValue“.

Em nosso exemplo, é exibido um botão de incremento, que pode ser escondido utilizando a propriedade “HideTrigger“, para “true” ou “false“, de acordo com a necessidade. Este incremento foi colocado na propriedade “Step“, que pode ser definida, caso contrário será 1 (um).

Data

Os campos de data possuem um pequeno calendário para auxiliar o usuário a informar a data corretamente. E também fazem a validação destes valores, evitando assim o usuário informar uma data errada.

Simples

<ext:DateField ID="DateField1" runat="server" FieldLabel="DateField">
</ext:DateField>

Calendário

<ext:DatePicker ID="DatePicker1" runat="server">
</ext:DatePicker>

CheckBox

Os campos do tipo checkbox permitem que você tenha cada um com sua label ou apenas uma label escondendo as outras.

Cada um com sua label

<ext:Checkbox runat="server" BoxLabel="Impala 68">
 </ext:Checkbox>
 <ext:Checkbox runat="server" BoxLabel="Mustang GTO">
 </ext:Checkbox>
 <ext:Checkbox ID="Checkbox1" runat="server" BoxLabel="Ford Tudor">
 </ext:Checkbox>

Label em comum

<ext:Checkbox ID="Checkbox2" runat="server" BoxLabel="Impala 68" FieldLabel="Carros Preferidos">
 </ext:Checkbox>
 <ext:Checkbox ID="Checkbox3" runat="server" BoxLabel="Mustang GTO" HideEmptyLabel="false">
 </ext:Checkbox>
 <ext:Checkbox ID="Checkbox4" runat="server" BoxLabel="Ford Tudor" HideEmptyLabel="false">
 </ext:Checkbox>

Radio Buttons

A declaração dos Radiobuttons é parecida com a declaração dos Checkboxes, só que ao invés de usar a classe “Checkbox”, usamos a classe “Radio”.

note-taking Para o html entender em qual grupo deverá validar os Radiobuttons, estes deverão ter o mesmo nome (name) definido, no caso eu chamei os meus de “radinho”.

Cada um com sua label

<ext:Radio ID="Radio1" Name="radinho" runat="server" BoxLabel="Impala 68">
</ext:Radio>
<ext:Radio ID="Radio2" Name="radinho" runat="server" BoxLabel="Mustang GTO">
</ext:Radio>
<ext:Radio ID="Radio3" Name="radinho" runat="server" BoxLabel="Ford Tudor">
</ext:Radio>

Label em comum

<ext:Radio ID="Radio4" runat="server" BoxLabel="Impala 68" FieldLabel="Carro Preferido">
</ext:Radio>
<ext:Radio ID="Radio5" runat="server" BoxLabel="Mustang GTO" HideEmptyLabel="false">
</ext:Radio>
<ext:Radio ID="Radio6" runat="server" BoxLabel="Ford Tudor" HideEmptyLabel="false">
</ext:Radio>
note-taking Este foi deixado sem nome propositalmente para vermos a diferença de “com nome” e “sem nome

Vimos aqui alguns componentes básicos. Nos próximos capítulos, iremos ver componentes mais complexos, como ComboBox, GridPanels, Windows , etc.


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Visão geral dos componentes Ext.Net

2
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
16 de maio de 2014

Visao_Geral

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

o Ext.Net provê uma vasta quantidade de controles para utilizarmos no desenvolvimento das aplicações Web, como podemos ver na tabela abaixo, apenas um resumo das possibilidades.

Visualização de dados. DataView, GridPanel,PropertyGrid, TreePanel, Chart and Calendar
Manipulação dos dadaos Store, Proxy, Model, Reader/Writer
Contêineres Container, Panel, Window, ButtonGroup, Toolbar, ViewPort, TabPanel, Menu
Contêineres especiais Desktop e Portal
Controles Neste ponto temos vários, iremos ver sobres eles, tais como, Buttons, SplitButton,
LinkButton, Pickers (ColorPicker, DatePicker), Slider, ProgressBar … Etc.
Leiautes Accordion, Anchor, Border, HBox, VBox … Etc.
Formulários e Campos FormPanel, FieldContainer, TextField, NumberField, ComboBox, CheckBox, DataField,
DropDown, FileUpload … Etc.
Utilidades e Helpers DragDrop, KeyMap, KeyNav, XTemplate, TaskManager, Selection Model e XSxript

A lista não está completa, mas já temos uma visão da força que o Ext nós dá para desenvolvermos nossas aplicações Web, mais próximas da realidade em que o usuário Desktop está habituado.

Todos os controles são demonstrados no site de exemplos do Ext.Net, o site, para mim, é uma fonte de pesquisa que estou sempre utilizando.

A classe de base para os componentes é a “Component”, mas eu tenho por hábito, sempre criar meus componentes com base em um componente já pronto, por exemplo, se vou criar um campo de texto com alguma formatação específica, já faça a herança diretamente do componente “TextField”.

O Ext.Net provê várias formas de desenvolvimento de componentes do lado servidor, sem ter que nos preocuparmos com o lado cliente, pois todo o Javascript será gerado de forma automatizada. Mas, é interessante conhecer sobre o ExtJS, a comunidade está em constante crescimento e os exemplos são claros e objetivos.

Não é o intuito deste artigo explicar sobre ExtJS, para aprender um pouco mais sobre ExtJS a Loiane Groner escreveu um curso muito bom, segue o link:

No próximo artigo iremos ver sobre alguns componentes básicos e colocarmos a mão na massa. Até lá … 🙂


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Instalando o Ext.Net

4
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
6 de maio de 2014

Instalando_Ext.Net

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

Instalando o Ext.Net manualmente.

Neste tópico eu vou falar da instalação do Ext.Net, mas da forma trabalhosa, manualmente.

Ao final do artigo, tem o link para o vídeo do Geoffrey McGill, que demonstra como instalar utilizando o NuGet Package. (Mas ai não tem graça)

Então, mãos à obra.

Primeiramente, baixe a versão 2.5 WebForms do Ext.Net em Ext.NET.WebForms.Pro.2.5.1.zip.

Ao final do download descompacte o arquivo baixado, será criado alguns diretórios e arquivos, mas iremos nos ater apenas ao diretório “lib“.

Neste diretório existem 4 diretórios, onde cada diretório representa a versão do Framework que será utilizado para o desenvolvimento da sua aplicação, no nosso caso será o 4.0.

Dentro do diretório “~\lib\net40\” existe o arquivo “Ext.Net.dll“, é este que iremos referenciar mais logo a seguir.

Baixar as versões públicas do “Ext.Net.Utilities” e do “Transformer.NET” em https://github.com/extnet/

Compilar as versões baixadas.

Agora vamos ao Visual Studio, crie uma nova aplicação web vazia, pois iremos começar do zero.

Faça referência aos arquivos:

  1. ~\lib\net40\Ext.Net.dll“, ou a versão do Framework que você estiver utilizando;
  2. Ext.Net.Utilities.dll (dentro da pasta bin release/debug que foi compilado o projeto);
  3. Transformer.NET.dll (dentro da pasta bin release/debug que foi compilado o projeto);

Configurando o Web.Config

Abra o Web.Config no editor e vamos colocar a mão na massa:

Apague todo o conteúdo criado no web.config e vamos fazer uma sessão de cada vez:

  • Neste ponto definimos que a sessão de configuração do Ext.NET não necessita de nenhuma configuração especial no quesito segurança, para que possa sera acessada pela aplicação:
<configSections>
 <!--
 Para um melhor entendimento do atributo requirePermission:
 http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.requirepermission.aspx
 -->
 <section name="extnet" type="Ext.Net.GlobalConfig" requirePermission="false" />
 </configSections>
  • Definir o padrão de tema. O tema padrão pode ser um dos valores:
    • Default;
    • Gray;
    • Neptune;
    • Acess
<!--Define o tema padrão do ext.net-->
 <extnet theme="Gray" />
  • Definir os handlers, manipuladores, do Ext.Net
note-taking

O que são handlers (manipuladores)?

Os handlers, ou manipuladores, normalmente processam as requisições e não têm interatividade com o usuário, como páginas ou controles, e normalmente são responsáveis por camadas lógicas dentro da aplicação.

Podemos utilizar um handler quando precisamos executar algo no servidor sem a necessidade de intervenção do usuário final.

Os handlers implementam a interface IHttpHandler, o HttpHandler é responsável por atender as requisições do browser e a interface IHttpHandler possui as assinaturas necessárias para que estas requisições sejam atendidas.

<!--Define os handlers (manipuladores) do ext.net-->
 <httpHandlers>
 <add path="*/ext.axd" verb="*" type="Ext.Net.ResourceHandler" validate="false" />
 </httpHandlers>
  •  Define os módulos do Ext.NET
note-taking

O que são modules (módulos)?

Os módulos HTTP são executados antes e depois do handler (manipulador) e nos fornece métodos para interagir com a requisição (HttpRequest). Os módulos devem implementar a interface System.Web.IHttpModule.

São normalmente sincronizados com os eventos da classe System.Web.IHttpModule (implementado dentro do Global.asax.cs ou. vb).

A seguir uma lista de eventos que devem ser considerados na implementação do módulo:

  • BeginRequest
  • AuthenticateRequest
  • AuthorizeRequest
  • ResolveRequestCache
  • AcquireRequestState
  • PreRequestHandlerExecute
  • PostRequestHandlerExecute
  • ReleaseRequestState
  • UpdateRequestCache
  • EndRequest
  • * PreSendRequestHeaders
  • * PreSendRequestContent
  • * error

Os eventos identificados por um asterisco (*) pode ocorrer a qualquer momento dentro da requisição, todos os outros estão listados em sua ordem de chamada.

<!--Define os módulos do ext.net-->
 <httpModules>
 <add name="DirectRequestModule" type="Ext.Net.DirectRequestModule, Ext.Net" />
 </httpModules>
  • Definir a marcação “ext” para toda página ou componente que for criado para o “ext”;
<pages>
 <controls>
 <!--Indica que toda página criada irá ter a diretiva "ext" como padrão para ser usada como marcação na criação.-->
 <add assembly="Ext.Net" namespace="Ext.Net" tagPrefix="ext" />
 </controls>
 </pages>
  • Se estiver executando o IIS 7 como servidor, devemos utilizar a seguinte configuração no Web.Config;
<!-- Configurações para o IIS7 -->
 <system.webServer>
 <validation validateIntegratedModeConfiguration="false" />
<modules>
 <add name="DirectRequestModule" preCondition="managedHandler" type="Ext.Net.DirectRequestModule, Ext.Net" />
 </modules>
<handlers>
 <add name="DirectRequestHandler" verb="*" path="*/ext.axd" preCondition="integratedMode" type="Ext.Net.ResourceHandler" />
 </handlers>
 </system.webServer>
  • E por fim, informe os runtimes adicionais que serão utilizados no projeto;
 <runtime>
 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
 <dependentAssembly>
 <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
 <bindingRedirect oldVersion="1.0.0.0-5.0.8" newVersion="6.0.0" />
 </dependentAssembly>
 <dependentAssembly>
 <assemblyIdentity name="Ext.Net.Utilities" publicKeyToken="2c34ac34702a3c23" />
 <bindingRedirect oldVersion="0.0.0.0-2.3.0" newVersion="2.4.0" />
 </dependentAssembly>
 <dependentAssembly>
 <assemblyIdentity name="Transformer.NET" publicKeyToken="e274d618e7c603a7" />
 <bindingRedirect oldVersion="0.0.0.0-2.1.0" newVersion="2.1.1" />
 </dependentAssembly>
 </assemblyBinding>
 </runtime>

Ao final seu arquivo Web.Config deverá estar como abaixo, ou semelhante.

<?xml version="1.0"?>
<configuration>
 <configSections>
 <!--
 Para um melhor entendimento do atributo requirePermission:
 http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.requirepermission.aspx
 -->
 <section name="extnet" type="Ext.Net.GlobalConfig" requirePermission="false"/>
 </configSections>
 <!--Define o tema padrão do ext.net-->
 <extnet theme="Gray"/>
 <system.web>
 <!--Define os handlers (manipuladores) do ext.net-->
 <httpHandlers>
 <add path="*/ext.axd" verb="*" type="Ext.Net.ResourceHandler" validate="false"/>
 </httpHandlers>
 <!--Define os módulos do ext.net-->
 <httpModules>
 <add name="DirectRequestModule" type="Ext.Net.DirectRequestModule, Ext.Net"/>
 </httpModules>
 <pages>
 <controls>
 <!--Indica que toda página criada irá ter a diretiva "ext" como padrão para ser usada como marcação na criação.-->
 <add assembly="Ext.Net" namespace="Ext.Net" tagPrefix="ext"/>
 </controls>
 </pages>
 <compilation debug="true"/>
 </system.web>
 <!-- Configurações para o IIS7 -->
 <system.webServer>
 <validation validateIntegratedModeConfiguration="false"/>
 <modules>
 <add name="DirectRequestModule" preCondition="managedHandler" type="Ext.Net.DirectRequestModule, Ext.Net"/>
 </modules>
 <handlers>
 <add name="DirectRequestHandler" verb="*" path="*/ext.axd" preCondition="integratedMode" type="Ext.Net.ResourceHandler"/>
 </handlers>
 </system.webServer>
 <runtime>
 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
 <dependentAssembly>
 <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed"/>
 <bindingRedirect oldVersion="1.0.0.0-5.0.8" newVersion="6.0.0"/>
 </dependentAssembly>
 <dependentAssembly>
 <assemblyIdentity name="Ext.Net.Utilities" publicKeyToken="2c34ac34702a3c23"/>
 <bindingRedirect oldVersion="0.0.0.0-2.3.0" newVersion="2.4.0"/>
 </dependentAssembly>
 <dependentAssembly>
 <assemblyIdentity name="Transformer.NET" publicKeyToken="e274d618e7c603a7"/>
 <bindingRedirect oldVersion="0.0.0.0-2.1.0" newVersion="2.1.1"/>
 </dependentAssembly>
 </assemblyBinding>
 </runtime>
</configuration>

Testando a instalação

Adicione um novo webform ao projeto chamado “Default.aspx”.

Neste form, como de praxe :), Iremos criar um “Olá Ext.Net”.

Não se preocupe com o código em questão, pois será discutido nos próximos artigos.

Em Code Design adicione o seguinte código:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Ext.Net.Tutorial.Default" %>
<!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>
    <ext:ResourceManager runat="server">
    </ext:ResourceManager>
    <form id="form1" runat="server">
    <ext:Button runat="server" ID="btnOla" Text="Olá Ext.Net">
        <DirectEvents>
            <Click OnEvent="btnOla_Click">
            </Click>
        </DirectEvents>
    </ext:Button>
    </form>
</body>
</html>

Em Code Behind adicione o seguinte código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Ext.Net.Tutorial
{
    public partial class Default: System.Web.UI.Page
    {
        protected void btnOla_Click(object sender, DirectEventArgs e)
        {
            X.Msg.Show(new MessageBoxConfig
            {
                Title = "Ext.NET",
                Buttons = MessageBox.Button.OK,
                Icon = MessageBox.Icon.INFO,
                Message = "Olá Ext.NET"
            });
        }
    }
}

Execute a aplicação e clique no botão. A mensagem “Olá Ext.NET” deverá ser exibida em uma caixa de mensagem do navegador.

Se isto acontecer, o Ext.NET foi configurado corretamente e podemos continuar com nosso aprendizado.

Se foi lançado algum erro, verifique se é um dos listados abaixo, caso não for, verifique a solução no fórum:

Fórum Oficial: http://forums.ext.net/

Nosso Fórum: forum/ext-net/

Resolvendo erros

The ResourceManager Control is missing from this Page.

Adicione a marcação

<ext:ResourceManager runat="server">
</ext:ResourceManager>

logo após a tag <body>.

Marca de servidor desconhecida: ‘ext:<name>’.

Verifique se no Web.Config se a diretiva <add assembly> foi informada.

 <pages>
<controls>
<!--Indica que toda página criada irá ter a diretiva "ext" como padrão para ser usada como marcação na criação.-->
<add assembly="Ext.Net" namespace="Ext.Net" tagPrefix="ext"/>
</controls>
</pages>

CS1061: ‘ASP.default_aspx’ não contém uma definição para ‘btnOla_Click’ e nenhum método de extensão ‘btnOla_Click’ aceita que um primeiro argumento de tipo ‘ASP.default_aspx’ seja encontrado (você não está usando uma diretriz ou referência de assembly?)

Quando definimos um “DirectMethod” pelo Code Design é necessário que o método que irá tratar o evento seja definido como “protected” ou “public” no Code Behind.

The web.config file for this project is missing the required DirectRequestModule.

Inserir a diretiva

<httpModules>
<add name="DirectRequestModule" type="Ext.Net.DirectRequestModule, Ext.Net"/>
</httpModules>

pois o Ext.NET depende do módulo “DirectRequest” para construir o lado cliente.

Instalando usando o NuGet Package

E como prometido, segue o vídeo da instalação pelo NuGet.

YouTube responded to TubePress with an HTTP 410 - No longer available

Conhecendo os arquivos.

  • Ext.Net.dll: Assembly principal do Ext.NET;
  • Ext.Net.xml: Arquivo de IntelliSense para ajudá-lo enquanto você codifica;
  • Ext.Net.Utilities.dll: Utilitários do Ext.NET framework (Muito úteis);
  • Ext.Net.Utilities.xml: IntelliSense para o utilitário;
  • NewtonSoft.Json.dll:  Json.NET framework utilizado pelo Ext.NET;
  • NewtonSoft.Json.xml: O  IntelliSense do Json.NET;
  • Transformer.NET.dll: Um biblioteca  .NET para análise e transformação de dados;
  • Transformer.NET.xml:  IntelliSense do Transformer.NET;

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Apresentando o Ext.Net

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (1 votos, média: 5,00 de 5)
Loading...
5 de maio de 2014

Apresentando_Ext.Net

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

O que é Ext.NET?

Ext.NET é um framework de código fonte aberto, de componentes  ASP.NET  (WebForm + MVC) integrado ao framework Ext JS.

O site oficial Ext.NET é:

Site oficial do Sencha:

Ext.NET  (pronuncia-se -eee-ecks-T dot NET), eu pronuncio “EXT.NET” mesmo 🙂 .

Em outras palavras, é um conjunto de controles e classes, que geram JavaScript , HTML e CSS sempre que necessário, e, que este JavaScript tem como base a estrutura do Ext JS.

O Ext.NET também inclui componentes que não são encontrados em Ext JS, estende várias classes, sempre que necessário, proporcionando assim sua própria camada JavaScript.

O Ext.NET é uma abstração do Ext JS. Esta abstração não é uma camada fraca ou
restritiva, se assim desejar, você pode escrever diretamente na camada Ext JS baseada em JavaScript.

note-taking Eu particularmente escrevo todos os componentes do lado servidor quando preciso de um novo.
Tenho esta visão devido à facilidade que é oferecida pelo Ext.Net no lado servidor.

Uma outra forma de ver, é pensar no Ext.NET como uma ponte entre Ext JS no
lado cliente e ASP.NET no lado servidor.

A relação com ASP.NET

note-taking A escolha da linha de desenvolvimento, WebForms ou MVC não é importante para este artigo como um todo. Mas toda a apresentação será feita em WebForms.

Se você está acostumado com a criação de aplicações ASP.NET usando controles que seguem o padrão ASP.NET, que mantêm seu estado no ViewState, o Ext.NET pode parecer familiar, mas com muitas melhorias:

  • O “ViewState” não é requerido pelo Ext.NET, podemos desligar e economizaremos uma quantidade de bytes para a aplicação cliente.
    • A não ser que você esteja usando “FormAuthentication”;
  • Uma aplicação ASP.NET Web Forms requer um único “<runat = “server” >” e já adicionará todos os eventos, métodos e propriedades e assim por diante ao componente. Com Ext.NET isto é opcional como será demonstrado;
  • Ao desenvolver aplicações ASP.NET, os controles são adicionados na coleção “Controls” do componente recipiente. Com Ext.NET, você normalmente adiciona componente filhos ao componente pai, usando a coleção “Items”. Tenha isso em mente, irá nos ajudar nos próximos capítulos;

Vamos nos concentrar um pouco no ViewState.

Em um desenvolvimento ASP tradicional, WebForms, o ViewState e o modelo PostBack são pontos chaves para recriar os controles complexos no estado em que o desenvolvedor e usuário espera que eles existam.

São feitos vários posts e esperado vários retornos; “response”; para as páginas que trafegam este “ViewState”.

Com Ext.NET, criamos uma interface rica, onde o estado dos controles não precisam ser mantidos no lado servidor.

As aplicações desenvolvidas utilizando Ext.Net utilizam-se da tecnologia AJAX, o que significa que podemos recarregar apenas o ponto em questão da página, ou fazer uma consulta sem modificar nada na página.

Exemplo:

Para validar algo no banco de dados e exibir uma mensagem ao usuário.

Para o lado cliente, o Ext.NET framework lida com toda a complexidade da manutenção dos controles, como a instanciação, destruição, layout e redesenho.

Mas, se mesmo assim você ainda precisar de mais, a API do Ext.NET é bastante flexível para que você possa colocar a mão na massa e desenvolver seu próprio componente, como será visto no artigo “Criando componentes no lado Servidor“.


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

O que é RIA (Rich Internet Application)?

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
25 de abril de 2014

evolution-of-user-interface-from-mainframe-to-ria

Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)

O que é RIA?

Aplicação de Internet Rica; RIA (Rich Internet Application); São aplicações que possuem como característica as facilidades das aplicações desenvolvidas em Desktop.

Têm um visual onde não existe a necessidade de se atualizar toda a página, conceito “Ajax“, ou até mesmo sem atualização, conceito chamado de “no-refresh“, o que vai de encontro com o conceito de “HduX (High Definition User eXperience)

Como surgiu o RIA

A internet surgiu com páginas em um modelo estático, onde toda atualização era necessário enviar os dados ao servidor, este por sua vez processava a nova página e devolvia ao navegador, que por sua vez interpretava as páginas e exibia-as ao usuário.

http_diagram
Dentro desta necessidade, de as páginas não serem tão estáticas, a  “Netscape“, por volta de 1995 resolve lançar o Javascript.

question A intenção do javascript era deixar algo dinâmico …Que nasceu com o propósito de ser estático…Não seria isso uma gambiarra da web?

Mas com o crescimento das aplicações de negócios, B2B, diferente das aplicações simples, estas exigiam várias páginas de formulários para completar uma simples transação, e como foi dito acima, para cada “post” ia toda a página ao servidor e este retornava a nova página, isso diminuía a performance das páginas e servidores web.

Tendo em vista esta necessidade, em 1996 a Microsoft lançou a tag <iframe> que permitia que o conteúdo fosse carregado de forma assíncrona.

Em 1999 a Microsoft criou o primeiro componente de requisição, o “XMLHTTP ActiveX” para o Internet Explorer, o que mais tarde seria adotado pela Mozilla, Safari, Ópera sob o nome de XMLHttpRequest e posteriormente a Microsoft também adotou este nome em seu navegador.

note-taking O termo “Ajax” foi afirmado publicamente em Fevereiro de 2005 por
Jesse James Garrett, em um artigo intitulado “Ajax: Uma Nova Abordagem para Aplicações Web“.

ajax-lifecycle

Benefícios

Devido ao RIA ter sua “Client Engine”, isso nos leva à alguns pontos benéficos:

  • Riqueza: É possível oferecer ao usuário uma interface rica, que não pode ser feita apenas com o uso de HTML simples. A possibilidade de arrastar e soltar, incluir campos dinamicamente, cálculos realizados diretamente do lado cliente, fazem a diferença;
  • Resposta: A resposta rápida que acontece do lado cliente, ou mesmo quando há a interação do lado servidor, não há a necessidade de se enviar toda a página ao servidor, a atualização acontece apenas no ponto da página que foi modificada;
  • Processamento Cliente/ Servidor: A carga de processamento entre o cliente e o servidor é dividida, pois o servidor web não precisa realizar todo o processamento da página para devolver ao usuário;
  • Comunicação Assíncrona: Quando o usuário realiza uma ação, não é necessário esperar a resposta do servidor. As páginas podem prever uma ação futura e já deixar carregados no lado cliente, antes da solicitação do usuário, como é  o caso do Google Maps;
  • Sandbox: Ao serem executadas em uma Sandbox, não existe o acesso ao sistema do usuário, o que garante um certo nível de segurança.

Falhas

  • Scripts Desabilitados:  Se por alguma razão o usuário desabilitar o javascript, as páginas em RIA não irão funcionar
    • Atualmente não vejo o por quê disso.

 


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Rich Internet Applications com Ext.Net

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
25 de abril de 2014

rich-internet-applications-ext

Salve galera.

Depois de muito tempo sem postar devido há uma boa guinada em minha vida pessoal e profissional; mudança de cidade, de emprego… Logo… acabei deixando o site de lado… Mas nunca esquecido.

E para retornar  com chave de ouro, irei falar sobre como construir uma aplicação Web rica utilizando o componente  Ext.Net.

Abaixo o índice do que será discutido neste artigo, e  o mesmo será apresentado, por mim, no evento Devcon Gescla, http://www.devcongescla.com.br.

Sumário

  1. O que é RIA;
  2. Apresentando o Ext.Net;
  3. Instalando o Ext.Net;
  4. Utilizando os componentes básicos;
  5. Utilizando o componente Window;
  6. Definindo leiautes;
  7. Utilizando Listeners (Eventos no lado cliente) e DirectEvents (Lado Servidor);
  8. Criando métodos no lado Cliente/Servidor (DirectMethod);
  9. Trabalhando com dados, Combobox e GridPanel;
  10. Criando componentes no lado Servidor;

Links Úteis


É isso ai pessoal 🙂 Até o próximo ♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s