martedì 30 agosto 2011

How To: javascript ceil e floor

Ceil e Floor in javascript restituiscono un numero arrotondato per eccesso nel primo caso e per difetto nel secondo.

Entrambi appartengono a Math e il loro utilizzo è discretamente diffuso, soprattutto se si sta realizzando un applicazione dove è necessario verificare i dati immessi in
un form ( posto che questi siano numeri ).

Math.ceil(9.9) restituisce 10
Math.floor(9.9) restituisce 9

Di contro potrebbe essere plausibile comprendere quali dei due arrotondamenti utilizzare e in che misura.

var y = 0;

if (Math.ceil(x) == Math.floor(x))
{
// in questo caso è uguale
y =Math.ceil(x);
}
else
{
// esempio
// 10 è il ceil di 9,1
// ma evidentemente vogliamo
// ottenere 9 e non 10
if ( Math.ceil(x)-x > 0)
{
y =Math.floor(x);
}
else
{
y =Math.floor(x);
}
}


In questo caso un esempio di come si potrebbero utilizzare sia il ceil che il floor.

lunedì 29 agosto 2011

How To: javascript Random

Ecco un banale esempio di come ottenere un numero pseudocausale in javascript.

Math.random();

Il metodo deriva dall'oggetto Math, che presenta le principali funzioni matematiche.

Le possibili variazioni sul caso possono essere:

Math.floor(Math.random()*x);

dove floor consente di arrotondare un numero al PIU' basso intero.
Se avete per esempio Math.floor(3.2) il risultato sarà 3
Se avete per esempio Math.floor(3.7) il risultato sarà 3


dove x è un numero per cui ingrandire il risultato di random.

domenica 28 agosto 2011

How To: Create Event in Javascript

Che cos'e' un evento ??? Per javascritp un evento è il frutto di una azione scatenata da un altra azione.

Per ogni azione esiste una reazione uguale e contraria cita la dinamica, ma non è questo il caso.

Creare un evento implica che si sta realizzando un oggetto che consenta la creazione di un delegato che possa gestire l'evento.

Per fare un esempio comprensibile, "Preparare la tavola" è l'evento, l'ora di cena attiva la Mamma che scatena l'evento "Preparare la tavola" e noi siamo i delegati al compito !

function Mamma()

{
this.onOraDiCena = null;
this.OraDiCena = null;

Mamma.prototype.getValue = function () {
return this.OraDiCena;
}

Mamma.prototype.setValue = function (v) {
this.OraDiCena = v;

if (this.OraDiCena =true)
{
if (typeof this.onOraDiCena == 'function')
this.onOraDiCena ();
}
}
}


function DoPreparaTavola ()
{
alert ("E' ora di cena Prepara la tavola " );
}

var oMamma = new Mamma ();
oMamma.onOraDiCena = DoPreparaTavola;
o.OraDiCena (true);


Ed ecco l'esempio "pratico pratico! "
( buon appetito, e non dimenticate i tovaglioli !!)

sabato 27 agosto 2011

XA.EF Entity framework (4)

Benchè nel terzo capitolo abbia speso qualche parola per la costruzione di una proprietà c'e' da aggiungere ancora molto altro. Indubbiamente mancano gli attributi, custom o dipendenti da Linq to Sql.

Verosimilmente il concetto di attributo dovrebbe essere quanto di più esplicativo per il destino della proprietà stessa, ma deve dare anche un "lume" su come potremo utilizzare la proprietà o se questa sarà visibile o meno.

Questo punto diciamo che decisamente "analitico" ossia, dato che l'implementazione è ancora molto lontana posso scegliere arbitrariamente di:

-presentare un form con tutti i campi di una tabella e attribuirgli la visibilità.
-dare la possibilità all'utente di modificare gli attributi agendo sul codice.

A ben pensarci il primo caso sembra sicuramente il più ovvio, di contro portei sfruttare quanto esposto nel post della persistenza, per avere un "registro di quanto implementato" per poi ripresentarlo all'utente che sta rigenerando le classi.

Sempre etendendo il ragionamento se genero tutto io, so che cosa ho generato. Ma gli utenti sono utenti ( e del resto anch'io ) quindi è noto il fatto che lanciato un script si ha "il prurito" di vedere che cosa è sucesso.
Quindi tanto vale lasciare la possibilità all'utente di modificare il codice generato.

Una versione semplificata di questi attributi potrebbe essere resa tramite quanto segue.

using System;

using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace XA.EF.Test
{

[System.AttributeUsage(
AttributeTargets.Class|
AttributeTargets.Field|
AttributeTargets.Property,
AllowMultiple = true)]
public class DbMapperAttribute:System.Attribute
{
private string _dbFieldName;
private string _mappingEntity;
private string _headerOrCaption;
private eFieldVisibility _visibility;
private int _columnOrder;

public string dbFieldName
{
get { return _dbFieldName; }
}

public string mappingEntity
{
get { return _mappingEntity; }
}

public string headrOrCaption
{
get { return _headerOrCaption; }
}

public int columnOrder
{
get { return _columnOrder; }
}

public eFieldVisibility visibility
{
get { return _visibility; }
}

public DbMapperAttribute(
int ColumnOrder,
string DbFieldName,
string MappingEntity,
string HeaderOrCaption,
eFieldVisibility Visibility
)
{
_dbFieldName = DbFieldName ;
_mappingEntity = MappingEntity;
_headerOrCaption = HeaderOrCaption;
_visibility = Visibility;
_columnOrder = ColumnOrder;
}
}
}


e per dar maggior chiarezza, questo è l'enumerativo che utilizzo.

using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace XA.EF.Test
{
public enum eFieldVisibility
{
none,
grid,
details,
both
}
}


Tuttavia è facile comprendere che l'attributo derivante servirà anche per mostrare o non mostrare l'elemento in una griglia o in un form di dettaglio.

Ciò detto mi è utile considerare sempre più che per la realizzazione di un E.F. strutturato e elastico è sicuramente necessario scrivere una serie di classi che vadano ben oltre alle entità.

venerdì 26 agosto 2011

How To: object persistence c#

Per prima cosa chiariamo il concetto di "persistenza".

L'argomento è molto vario, c'e' chi sottintende con persitenza la possibilità di mantenere il valore di un oggetto per la durata di tutta una sessione di lavoro.
E quindi questo implica che l'oggetto stesso sarà di tipo statico. Il che non implica
nulla di diverso dal modificatore d'accesso "static".

C'e' chi per persitenza intende il salvataggio fisico del Dato su db, ma questo implica
che il tipo stesso sarà un entity e probabilmente ha vita e logica direttamente legate
al db stesso.

Quindi quali di questi sostenitori hanno ragione? In parte entrambi, in parte nessuno,
perchè entrambe le definizioni sono carenti o meglio incomplete.

Un oggetto persistente è un classe, che "dopo l'utilizzo", "dopo la distruzione", "dopo aver chiuso e riaperto la nostra applicazione" ripresenta i dati.

Qui qualcuno potrebbe dire Bella scoperta li pre imposto by Default, già ma questa non è persistenza è pre impostazione.

Partiamo quindi con un esempietto che ci permetterà di meglio comprendere la situazione:

public class UserDefinitions

{
private string _Alias;
public string Name { get; set; }
public string Surname { get; set; }
public string Alias
{
get { return _Alias; }
set { _Alias = value; }
}
public DateTime LastAccess { get; set; }
}


Si tratta di un oggetto più o meno semplice, il cui scopo è "mantenere" vive le informazioni di un utente.
Non è difficile notare che ho già fatto in modo che la property Alias già nasconda il field _Alias. Ci servirà per l'esempio.

Così come ci servirà nell'esempio anche quanto già scrissi per la serializzazione ..

public static class XmlDeSerializerTool

{

public static void Serialize<T>(string fileName, T elements)
{
TextWriter tw = new StreamWriter(fileName);
XmlSerializer xmls = new XmlSerializer(typeof(T));
xmls.Serialize(tw, elements);

tw.Close();
tw = null;
xmls = null;
}

public static T Deserialize<T>(string fileName)
{
Type e = typeof(T);

T elements = (T)Activator.CreateInstance(e);

TextReader tr = new StreamReader(fileName);
XmlSerializer xmls = new XmlSerializer(typeof(T));

elements = (T)xmls.Deserialize(tr);

tr.Close();
tr = null;
xmls = null;

return elements;
}
}


Che "come al solito riciclo per questioni di comodità".

Quindi la nostra classe assume un aspetto più interessante, implementado un evento, direttamente da component model.

public class UserDefinitions :System.ComponentModel.INotifyPropertyChanged

{
public event PropertyChangedEventHandler PropertyChanged;

private string _Alias;

public string Name { get; set; }
public string Surname { get; set; }
public string Alias
{
get { return _Alias; }
set {
_Alias = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Alias"));
}
}
}
public DateTime LastAccess { get; set; }

}


Questo per definizione ha già la possibilità di indicare quale proprietà è cambiata.

Una breve precisazione, utilizzando il mio DE/SErializzatore non è necessario implementare il costruttore, ne gli attributi necessari per la serializzazione, ma questo lo si deve in parte a XmlSerializer.

A questo punto creiamo un caso di test.

static void Main(string[] args)

{

UserDefinitions ud = new UserDefinitions();
if (File.Exists(@"c:\myData.xml"))
{
ud = XmlDeSerializerTool.Deserialize<UserDefinitions>(@"c:\myData.xml");
}
else
{
ud.Name = "Fabio";
ud.Surname = "Arosio";
ud.Alias = "TheMa!";
}
ud.PropertyChanged += new PropertyChangedEventHandler(us_PropertyChanged);
ud.LastAccess = DateTime.Now;
}


e qui il delegato per la gestione della propertyChange

public class UserDefinitions :System.ComponentModel.INotifyPropertyChanged

{
public event PropertyChangedEventHandler PropertyChanged;

private string _Alias;

public string Name { get; set; }
public string Surname { get; set; }
public string Alias
{
get { return _Alias; }
set {
_Alias = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Alias"));
}
}
}
public DateTime LastAccess { get; set; }

}


Di concetto questo caso ha poco valore, se non pochissimo, ma mi è servito per salvare il file xml e per mostrarne il contenuto.

<?xml version="1.0" encoding="utf-8"?>

<UserDefinitions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Fabio</Name>
<Surname>Arosio</Surname>
<Alias>TheMa!</Alias>
<LastAccess>
2011-08-26T15:18:34.1125638+02:00
</LastAccess>
</UserDefinitions>


E bene questa è la nostra "persistenza".

Attenzione non stiamo parlando di soli dati, ma anche della struttura del dato, non del singolo valore.

Di contro questo concetto sembra molto complesso, anche se secondo me, i dubbi nascono su che cosa realmente deve essere inteso come "persistente", e non tanto su come deve
avvenire la persistenza.




lunedì 15 agosto 2011

XA.EF Entity framework (3)

Per le entity e la collezione rimango ancora due o tre cosuccie da definire.

Dato che a priori non potrò sapere in quale lingua è stato realizzato il db e dato che non voglio studiarmi, quanto meno per il momento, una regular expression, per definire i singolari e i plurali.

Utilizzerò questa convenzione:
-NomeEntita = NomeTabella,
-NomeCollezione = NomeTabella_List,
-NomeAdapter = NomeTabella_Adapter.

Che per il momento ritengo valida e plausibile. Di contro c'e' ancora da considerare come si potrà utilizzare questo prodotto.

La prima idea è stata di realizzare un plugin per la ide, ma non mi ha convinto del tutto. Ritengo che la realizzazione di un prodotto Stand Alone possa dare maggior equilibrio, certo è vero che questo presupposto allontana un po' dall'usabilità stessa.

Quindi tornando alle mie preziose definizioni, direi che per l'entità posso raccogliere:
-Using ( servono sempre )
-Namespace ( per forza )
-Modificatore
-Nome classe
-Elenco di Field
-Elenco di Property
-Flag per creare il costruttore
-Flag per creare il distruttore
-Override di ToString ( che lascerò come fisso ... vedi post: ToString


Questo implica che dovrò implementare un writer overridabile per ogni elemento presente in questa lista.
Non solo devo creare anche un Tipo per i Field e un tipo per le proprietà, in questo modo prevengo il dover effettuare un continuo accesso al db.
Di concetto mi piacerebbe estrarre tutto fin dall'inizio, leggerlo e processarlo. Mi sta quasi balenando l'idea di creare un seriliazzatore anche se forse non è il caso.

public class PropertyPrototype

{
private string _accessType;
private string _valueType;
private string _name;
private string _description;
private bool _isReadOnly;

public string AccessType
{
get { return _accessType; }
set { _accessType = value; }
}

public string ValueType
{
get { return _valueType; }
set { _valueType = value; }
}

public string Name
{
get { return _name; }
set { _name = value; }
}

public string Description
{
get { return _description; }
set { _description = value; }
}

public bool IsReadOnly
{
get { return _isReadOnly; }
set { _isReadOnly = value; }
}
}


Partendo quindi dal prototipo più interessante mi sono ricavato questa classe, che per il momento descrive egreggiamente una proprietà.

public class PropertiesPrototype : List<PropertyPrototype>

{

}


E giusto per non smentirmi questa è la mia collezione.

domenica 14 agosto 2011

XA.EF Entity framework (2)

Il post precedente si era concluso con queste affermazioni:

L'Entità per il mio framework deve:
A)contenere delle proprietà che rappresentino la fonte da cui arriva,
B)contenere un metodo o un delegato che ne esegua la traccia,
C)contenere un evento che mi sappia indicare che lo stato è cambiato.


La collezione di elementi per il mio Entity Framork:
A)sarà reso con un lista,
B)conterrà i commenti come per l'entità,
C)non avrà bisogno d'altro.


Entrambe vere e parzialmente incomplete. Nel senso che mi ero già permesso di asserire, che avrei lasciato spazio a più possibilità. Quindi questo implica che volendo un utente potrà comunque scrivere una sua entità, magari indipendente dalla base dati da cui siamo partiti per realizzare le nostre entità.

Quindi potrbbe tornarci utile avere una base astratta che rappresenti l'entità

abstract class XAEntiy

{
public event EventHandler

}

delegate void XAEntityChangedEventHandler(XAEntityChangedEventArg Args);


class XAEntityChangedEventArg : EventArgs
{
public string ActualEntityValue { get; set; }

public XAEntityChangedEventArg( string Arg )
{
ActualEntityValue =Arg ;
}
}


abstract class XAEntiy
{
public event XAEntityChangedEventHandler StatusChanged;
}


Il tutto potrebbe sembra decisamente incomprensibile, ma analizzando il codice scopriamo che :
delegate void XAEntityChangedEventHandler(XAEntityChangedEventArg Args);


Sarà il nostro delegato che firma l'evento.

In più abbiamo anche gli eventuli argomenti legati all'evento, e di seguito la classe
astratta.

abstract class XAEntiy

{
public event XAEntityChangedEventHandler StatusChanged;
}



Tuttavia, vorrei anche implementare un interfaccia IXAEntity che ci darà la possibilità di avere un legame forte con la struttra.

In tutto questo emerge che il mio E.F. fondamentalmente si occuperà di scrivere le classi e di renderle sempre disponibili. Verosimilmente l'idea ora mi convince, tuttavia ho qualche dubbio sulla sincornizzazione.

Quindi :

L'Entità per il mio framework deve:
A)contenere delle proprietà che rappresentino la fonte da cui arriva,
B)contenere un metodo o un delegato che ne esegua la traccia,
C)contenere un evento che mi sappia indicare che lo stato è cambiato,
E)Implementeranno un interfaccia, un contratto solido,
F)una base astratta per tutti quello che non dovrà essere reimplemenato.
G)Le mie classi saranno scritte fisicamente nella soluzione.

XA.EF Entity framework (1)

Dopo una ricerca di quello che il web propone, mi sono proposto di realizzare il mio Entity Framework.

Mi sono deciso di pubblicare tutto il mio processo di realizzazione, perchè sono sicuro che tanti come me si sono un po' stancati di scaricare "cose" non estensibili, di provare del codice che "se c'e' uno spazio in una cartella non va", di agganciarsi librerie che "non vanno se non siete connessi a internet".

Che cos'e' un Entity Framework
Semplicemente si tratta di un processo, che data una connessione ad una fonte dati abbia la capacità di ricostruire sotto forma di codice le classi che rappresentano lo schema dati.
Tante parole che spiegano e non spiegano, ma come al solito un esempio vale più di mille parole.

Supponiamo di aver un Db che contiene due Tabelle:
Amici
- idAmico
- idTipoAmico
- Cognome
- Nome

TipoAmici
-idTipo_Amico
-Nome_TipoAmico
-Descrizione_TipoAmico

Un entity framework che si rispetti, dovrebbe, dopo un analisi del db, fornirci come Entity:

class Amico

{
public int idAmico {get;set;}
public int idTipoAmico { get; set;}
public string Cognome {get; set;}
public string Nome {get; set;}
}

class Amici :List<Amico>
{
}

class TipoAmico
{
public int idTipoAmico { get; set;}
public string Nome_TipoAmico { get; set;}
public string Descrizione_TipoAmico { get; set;}
}

class TipoAmici :List<TipoAmico>
{
}


Ma, ci dovrebbe fornire anche qualcosa in più, ossia la classe che si occuperà fisicamente di leggere e scrivere su DB, ossia la classe che si occuperà del vero lavoro.

class AmicoAdapter

{
public int Insert(Amico item)
{
// istruzione sql per insert
}
public void Edit(Amico item)
{
// istruzione sql per update
}
public void Delete(Amico Item)
{
// istruzione sql per delete
}
public List<Amico> Select ()
{
// istruzione sql per select
{
}



Naturalmente si tratta di esempi e quindi non mi cimenterò nella scrittura approfondita del codice. Anzi, per il momento non la considero proprio.

A bene vedere e a ben comprendere un Entity Framework altro non fa che "levarci le castagne dal fuoco" ossia realizza per noi delle classi che ci serviranno per la realizzazione di un progetto.


Perchè voglio realizzare un Entity Framework
La domanda è lecita, ma la risposta non è così scontanta.

Ogni azienda, grande o piccola deve provvedere alla tutela della sua proprietà intellettuale, al valore delle proprie buone pratiche e alla qualità di ciò che fornisce e fornirà ai suoi clienti.

E' quindi un MUST to Have provvedere alla realizzazione di un qualcosa che in parte assolva o garantisca un certo livello di qualità in questo compito.

Ponetevi la questione da un livello più alto, se vi trovate a dovere realizzare un applicazione con un db da 100 tabelle, davvero il primo pensiero e di raelizzare una ad una 100 classi per le entità e altrettante 100 per le collezioni? Direte al vostro manager, capo progetto, amministratore delegato che vi ci vorranno 100 giorni solo per
realizzare il telaio della base dati ?? Sono scelte io non lo farei...

Quindi realizzo questo Entity Framework sulla base della mia esigenza, ripromettendomi però di lasciare tanto spazio libero, non solo alle interpretazioni, ma a eventuali "plugin" che potranno dare maggior beneficio a chi "sfrutterà questa base".

Chiaramente, pubblicherò la maggior parte del codice, ma mi riservo di tenere qualcosa per me...

Che cosa mi/vi servirà
-SqlExpress
-VisualStudio
-C#
-Linq
-Conoscenze di base sugli oggetti Ado.Net
-Reflection ( credo proprio che mi servirà )
-Generic ( come sopra )
-Un po di conoscenza dei principali pattern.

Che cos'e' un Entity e che cosa deve Fare
Per quel che mi riguarda un entità altro non è che una classe, il cui scopo è di contenere delle informazioni relative ad una astrazione di dati.

Con astrazione di dati intendo che al momento non so e non voglio sapere da dove provengono e perchè.

Quindi l'esempio Amico, potrebbe andare anche bene, tuttavia si tratta di un qualcosa
di troppo passivo. Contiene e non fa altro, e ciò non è corretto.

Un esempio dovrebbe chiarire meglio la situazione:
Durante un processo d'inserimento dei dati in Amico, se volessi tracciarne il contenuto, dovrei interrogare proprietà per proprietà, con Amico la cosa è presto fatta, ma difficilmente ci va così bene.

Quindi alla mia classe Amico, manca un metodo che tracci il suo cambiamento e verosimilmente un evento che ci comunichi che lo stato è cambiato.

L'Entità per il mio framework deve:
A)contenere delle proprietà che rappresentino la fonte da cui arriva,
B)contenere un metodo o un delegato che ne esegua la traccia,
C)contenere un evento che mi sappia indicare che lo stato è cambiato.


E già che ci siamo visto che sono parecchio pignolo, la mia classe, dovrà
già anche implementare i commenti come summaries, perchè a ma piace avere un prodotto completo.

In questi commenti, mi piacerebbe anche avere l'autore, la data di creazione e nominalmente la fonte di provenienza.

Tuttavia, mi sembra che la mia Entità non sia ancora del tutto completa, perchè se per esempio dovessi avere due amici con lo stesso nome e con lo stesso cognome ?

Sarebbe carino avere la possibilità di clonare l'entità già implementando il necessario per farne una copia ? no ? NO! assolutamente no. Un entità deve essere anche un filo Stupida, perchè alla fine dei conti è solo un contenitore, che al massimo ci può dire quando è pieno.


Perchè usare una lista e non una dataTable
Mi appello al 5 emendamento di uno stato che non è il mio... ma avete presente quanto pesa una dataTable ? avete provato a usare Linq su una dataTable ? è un po come se per uccidere un insetto si ricorresse ad una bomba atomica.

Quindi userò una list senza troppi complimenti.

La collezione di elementi per il mio Entity Framork:
A)sarà reso con un lista,
B)conterrà i commenti come per l'entità,
C)non avrà bisogno d'altro.


How To: javascript Open Window

Una delle cose che generalmente ci si dimenta in jscript, è il sistema con cui aprire una nuova finestra.

Onestamente come pratica è un po in disuso, tuttavia potrebbe tornare comodo ricordarsi come si fa...

newWin = open("newDoc.html",

"Titolo di new Doc",
"toolbar=yes, resaizable=no, witdh=300,height=150");


Il primo parametro in questo esempio, è il documento che dobbiamo aprire,
il secondo parametro è il titolo della nuovo finestra,
il terzo è un aggregatore di informazioni per cui la nuova finestra sarà renderizzata.

In questo esempio specifico utilizzo toolbar, resaizable, witdh e height, ma ci sono un bel po di parametri in più.

loacation ( yes no),
direcories ( yes, no ),
status ( yes, no ),
menubar ( yes, no ),
scrolbars ( yes, no ).

Buon divertimento!

How To: javascript TypeOf.

Per chi ancora non lo sapesse è possibile in jscript richiedere all'oggetto che stiamo analizzando "di che tipo sei".

Il metodo in oggetto si chiama "typeof" è ci restituisce il tipo dell'oggetto.

document.write(typeof("io sono una string"));

document.write(typeof(true)); // restituisce bool


Naurtalmente è possibile richiedere i tipi anche per gli oggetti che eventualmente abbiamo creato noi !

Questo metodo torna decisamente utile se stiamo analizzando qualcosa che proviene da un web services realizzato da altri.

venerdì 12 agosto 2011

How To: Costum Control raise Events

Attenzione che questa è complessa.

Il mio scopo è quello di creare un controllo ( custom web control ) che contenga una Label, una TextBox e un Bottone, ora il necessario per l'esempio è una banalissima pagina Asp.Net che dovrà poi contenere il nostro controllo.

Nel mio caso la cosa non è poi così semplice, anzi questo è solo l'inizio.

Vi serve sicuramente comprendere a cosa serve quest' interfaccia IPostBackEventHandler anche onestamente che cosa avvenga "prima che si scateni il nostro evento" ha poco interesse.

using System;

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

namespace Test
{
[ToolboxData("<{0}:TextField runat=server></{0}:TextField>")]
public class TextField : WebControl ,IPostBackEventHandler
{
public event EventHandler StartSearch;

private string _referencedTableName = "";

private string _DataCaption = "default";

private string _DataValue;

private string _CssClassError;

private string _CssClassMaster;

private string _TxtLenght ="100";

public string referencedTableName
{
get { return _referencedTableName; }
set { _referencedTableName = value; }
}

public string DataCaption
{
get { return _DataCaption; }
set { _DataCaption = value; }
}

public string DataValue
{
get { return _DataValue; }
set { _DataValue = value; }
}

public string CssClassError
{
get { return _CssClassError; }
set { _CssClassError = value; }
}

public string CssClassMaster
{
get { return _CssClassMaster; }
set { _CssClassMaster = value; }
}

public string TxtLenght
{
get { return _TxtLenght; }
set { _TxtLenght = value; }
}

public Label labelText = new Label();
public TextBox textbox = new TextBox();
public Button btnSearch = new Button();

protected override void CreateChildControls()
{

this.EnableViewState = true;

Panel pnl = new Panel();

pnl.CssClass = _CssClassMaster;
Controls.Add(pnl);

labelText.Text = _DataCaption;
labelText.CssClass = "formLabel";
pnl.Controls.Add(labelText);

textbox.CssClass = "formText";
pnl.Controls.Add(textbox);

if (_TxtLenght != "")
{
textbox.Width = new Unit(_TxtLenght+ "px");
}

Literal lsp = new Literal();
lsp.Text = "&nbsp;&nbsp;&nbsp;";
pnl.Controls.Add(textbox);


btnSearch.Text = "...";
pnl.Controls.Add(textbox);

btnSearch.ID = "btnSearch_for_" +
_DataCaption.Replace(" ", "_").ToString();

btnSearch.Attributes.Add("onclick",
Page.ClientScript.GetPostBackEventReference
(this,btnSearch.ID.ToString()));

btnSearch.Attributes.Add("name", btnSearch.ID);

pnl.Controls.Add(btnSearch);


Literal l = new Literal();
l.Text = "<br/>";

pnl.Controls.Add(l);

}

public void RaisePostBackEvent(string eventArgument)
{
if (StartSearch != null)
{
StartSearch(textbox.Text, new EventArgs());
}
}
}
}



il tutto si concentra nel punto:

pnl.Controls.Add(textbox);


btnSearch.ID = "btnSearch_for_" +
_DataCaption.Replace(" ", "_").ToString();

btnSearch.Attributes.Add("onclick",
Page.ClientScript.GetPostBackEventReference
(this,btnSearch.ID.ToString()));

btnSearch.Attributes.Add("name", btnSearch.ID);

pnl.Controls.Add(btnSearch);


Momento in cui definiamo il controllo.

E qui

public void RaisePostBackEvent(string eventArgument)

{
if (StartSearch != null)
{
StartSearch(textbox.Text, new EventArgs());
}
}


Momento i cui definiamo l'evento.

Senza l'interfaccia l'evento non viene ne registrato ne gestito.

Per completare l'oggetto viserve :

Implemetare l'interfaccia IPostBackDataHandler

public virtual bool LoadPostData(string postDataKey, 

System.Collections.Specialized.NameValueCollection postCollection)
{
String presentValue = Text;
String postedValue = postCollection[postDataKey];

if (presentValue == null || !presentValue.Equals(postedValue))
{
Text = postedValue;
return true;
}

return false;
}


public void RaisePostDataChangedEvent()
{
if (TextChanged != null)
{
TextChanged(this, new EventArgs());
}
}


La proprietà che contiene il testo :

public String Text

{
get
{
return (String)ViewState["Text"];
}

set
{
ViewState["Text"] = value;
}
}


Ricordandovi di scrivere la EnabledViewState = true durante la creazione dei controlli.

E il gioco è fatto !

mercoledì 10 agosto 2011

How To: create a Virtual Property

Una delle tante possibilità offerte da "virtual" ( argomento discusso più volte nel blog ) è di poter ovviare all' new se abbiamo ereditato una classe.

In questo esempio propongo due versioni differenti della stessa classe, Property.
La prima cProperty contine una proprietà di tipo string.
La seconda vProperty contiene una proprietà virtuale di tipo string.

Le classi MyCProperty e MyVProperty ereditano rispettivamente cProperty e vProperty.

public class cProperty

{
private string _Property;
public string Property
{
get { return _Property; }
set { _Property = value; }
}
}

public class vProperty
{
private string _Property;
public virtual string Property
{
get { return _Property; }
set { _Property = value; }
}
}


public class MyCProprerty : cProperty
{
private string _Property;
public new string Property
{
get { return _Property; }
set { _Property = value; }
}
}

public class MyVProprerty : vProperty
{
private string _Property;

public override string Property
{
get { return _Property; }
set { _Property = value; }
}
}



Nel primo caso se tolgo il New e compilo il compilatore stesso mi avvisa che devo utilizzare il new.

Nel secondo caso se tolgo l' Ovveride e compilo il compilatore mi avvisa che la base espone già la stessa proprietà.

Rimane pur vero che in entrami i casi posso comunque sfruttare il polimorfismo e ottenere quindi qualcosa di simile.

public class TestCProperty : cProperty

{
private DateTime _NProperty = DateTime.Now;

public DateTime NProperty
{
get { return DateTime.Parse(Property); }
set { Property = value.ToString(); }
}
}


public class TestVProperty : vProperty
{
private DateTime _NProperty = DateTime.Now;

public DateTime NProperty
{
get { return DateTime.Parse(Property); }
set { Property = value.ToString(); }
}
}