martedì 29 marzo 2011

Regular Expression

Un mondo infinitamente bello ... con infinite regole...

Partendo da questo esempio mi piacerbbe dare qualche lume a chi non ne ha.

Validazione di un numero "float"
^\d*\,?\d*$ ogni numero + "," + ogni altro numero... questo valida
0,3 | ,3 | 3

Validazione di un numero con sole due posizioni decimali
^\d*\,?[0-9][0-9]$ ogni numero +"," + range da 0 a 9 + range da 0 a 9

Validazione di numeri inferiori a 10
^[0-9]{1}$


Validazione di numeri inferiori a 100
^[0-9]{2}$

Validazione di numeri inferiori a 1000
^[0-9]{3}$

Validazione di una data dd/mm/yyyy
^([0]?[1-9]|[1|2][0-9]|[3][0|1])[/]([0]?[1-9]|[1][0-2])[/]([0-9]{4})$

Per effettuare dei test e per verificare le vostre regular vi consiglio questo sito

http://www.regexplanet.com/

mercoledì 23 marzo 2011

Parent Refresh


Un pattern per definizione è "schema ricorrente" o meglio nell'ambito informatico è una soluzione progettuale a un problema ricorrente.

In questo mio caso di studio è in evidenza il rapporto fra un elemento Padre ed uno Figlio, tale per cui il figlio in autonomi modifica
il suo stato "Notificandolo" al padre. Il padre si aggiorna, e comunica al Figlio di aggiornarsi.

Pensate a due DataGrid in una web page connesse dal selected index della DataGrid Padre.. ora quando eseguiamo il bind l'indice va perso,
e di consenguenza si perde il puntamento sulla DataGrid Figlia.

Questo pattern applicato con giudizio, propone una soluzione, applicabile in cascata
padre-figlio,
nonno-padre-figlio,
bisnonno-nonno-padre-figlio...


classe per classe:

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

namespace ParentRefreshPattern
{
public class RefreshEventArg
{
private string _MethodName = "";
private bool _StateIsSaved = false;
private string[] _MethodArguments = { };

public string MethodName
{
get { return _MethodName; }
}

public bool StateIsSaved
{
get { return _StateIsSaved; }
}

public string[] MethodArguments
{
get { return _MethodArguments; }
}

public RefreshEventArg(string methodName, bool stateIsSaved, string[] methodArguments)
{
this._MethodName = methodName;
this._StateIsSaved = stateIsSaved;
this._MethodArguments = methodArguments;
}
}

public delegate void RefreshRequiredHandler(object sender, RefreshEventArg refreshEventArg);


public interface IParentRefresh
{
event RefreshRequiredHandler refreshHandlerForParent;
event EventHandler refreshForParent;

void SaveState();
void RestoreState();
}

public abstract class RefresherBase :IParentRefresh
{

public event RefreshRequiredHandler refreshHandlerForParent;
public event EventHandler refreshForParent;

protected static object _StateObject = null;

public virtual void SaveState()
{
_StateObject = this;

if (refreshHandlerForParent != null)
{
RefreshEventArg refArgs = new RefreshEventArg( "SaveState",true, new string[]{} );
refreshHandlerForParent(this, refArgs);
}

if (refreshForParent != null)
{
refreshForParent(this, new EventArgs());
}
}

public virtual void RestoreState()
{

}
}

public class Child : RefresherBase
{
private string field_001 = "";
private string field_002 = "";
private string field_003 = "";

public override void SaveState()
{
base.SaveState();
}

public override void RestoreState()
{
this.field_001 = ((Child)_StateObject).field_001;
this.field_002 = ((Child)_StateObject).field_002;
this.field_003 = ((Child)_StateObject).field_003;
}

public void DoSome()
{
field_001 = "111";
field_002 = "222";
field_003 = "333";
}
}


public class UseChild
{
public Child cld = new Child();

public UseChild()
{
cld.refreshForParent += new EventHandler(cld_refreshForParent);
cld.refreshHandlerForParent += new RefreshRequiredHandler(cld_refreshHandlerForParent);
}

void cld_refreshHandlerForParent(object sender, RefreshEventArg refreshEventArg)
{
Console.WriteLine("Child send request refresh");
cld.RestoreState();
}

void cld_refreshForParent(object sender, EventArgs e)
{
Console.WriteLine("Child send request refresh");
cld.RestoreState();
}
}
}


In questo modo utilizzando i dovuti accorgimenti si ottiene un andata ed un ritorno fra padre
e figlio senza troppe complicazioni.
Anche perchè il figlio in autonomia "sa salvare il proprio stato", e aggiornarsi alla richiamo.

Naturalmente e ccome sempre questo è uno spunto da cui partire.

venerdì 18 marzo 2011

Smart Observer (Eventi)

Un idea che mi ronza in tensta da un po' ...creare un entità osservabile.

La prima idea era di utilizzare quanto già realizzato nel Framework 4.0 ma poi come sempre per le piccole cose preferisco farmele da me.

Per due motivi semplici..
a) se voglio aggiungere o togliere qualcosa sono sempre in tempo
b) imparo comprendo apprendo.

Questo banale esempio rappresenta solo una parte di quello che realmente mi serve per realizzare una struttura del tutto affidabile.

Ma come per molti miei brani di codice, questa rappresenta benchè funzionante solo uno spunto.

Codice completo :

public delegate void OnChange(object Changed, string Message);

public interface INotifier
{
event OnChange Changed;
}

public class DemoEntity :INotifier
{
public event OnChange Changed;
private int _ID;
private string _Name;
public int ID
{
get { return _ID; }
set
{
_ID = value;
DoNotify();
}
}
public string Name
{
get { return _Name; }
set
{
_Name = value;
DoNotify();
}
}
public void DoNotify()
{
Changed(this, "Modified");
}
}

public class DemoListEntity : List , INotifier
{
public event OnChange Changed;
public void AddNewEntity(DemoEntity item)
{
this.Add(item);
DoNotify();
}
public void UpdateEnetity(DemoEntity item)
{
lock (this)
{
for (int i = 0; i < this.Count; i++) {
if (this[i].ID == item.ID) {
this[i] = item; DoNotify(); break; }
}
}
}
public void DoNotify() {
Changed(this, "Modified");
}


In questo esempio c'e' un delegato OnChange(object Changed, string Message);
Che per il momento non fa assolutemente nulla di interessante, ma ha lo scopo unico di
definire i campi che saranno oggetto della notifica di avvenuto cambiamento.C'è l'interfaccia INotifier che assume il ruolo di contratto fra chi utilizzerà l'evento e chi utilizzerà la classe.

Tipicamente potrebbe essere comodo utilizzae una lista di queste interfaccie al fine di concentrare la gestione dell'evento.

E poi due classi Entity e List per dar forma all'esempio.

In questa implementazione "banale e approssimativa" si può tuttavia comprendere quanto possa essere efficace.

L'uso di DoNotify potrebbe essere esteso con due parametri come il campo modificato e il valore attuale e precedente... per esempio ...

Il caso d'uso ?? Una window application verosimilmente a multi utenza a cui propagare che Un dato è stato modificato .. o che quello che stiamo visualizzando deve essere aggiornato.

Via web questo processo è sicuramente più complesso perchè chiaramente il server non può invocare una refresh lato client... ma il client via ajax può chiedere se qualcosa è cambiato...

In questo caso una struttura come questa non basta, perchè due sessioni non condividono la
stessa area di memoria .. ma nulla ci vieta di aggiornare dei dati lato server.



venerdì 11 marzo 2011

History in javascript e jquery

Posto che probabilmente creare un back all'interno della propria soluzione sia più che discutibile c'e' un sistema più o meno semplice ed elegante per farlo.

$(document).ready(function() {
var iLenght = window.history.length;

$("#pnlHistory").hide();

if (iLenght>2)
{
$("#pnlHistory").show();
}

});

Il codice è davvero fin troppo semplice per meritare grandi spiegazioni, tuttavia questo potrebbe essere solo il punto di partenza.
-parte nella document ready di una SiteMaster
-verifica il conteggio degli elementi nella history

Nel mio caso la logica implementata è di tener traccia dalla seconda pagina in
avanti.

pnlHistory è un div con un link, un immage button, un image con link oppure quello che più vi pare, sappiate che dovete realizzarlo voi.

mercoledì 9 marzo 2011

TextBox Auto Height in Grid view.

In molti casi siamo costretti a utilizzare una textbox con multi line in una grid view, tuttavia questa non ha modo di sapere quante righe conterrà... e all'interno della griglia ci appaiono
delle simpatiche barre che rischiano di coprire il testo.

Con questo sistema un filino brutale.. il problema è risolto.

protected void grvMyGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row != null && e.Row.RowType == DataControlRowType.DataRow)
{
TextBox b = (TextBox)e.Row.Cells[3].Controls[1];
int cRows = b.Text.Count(c => c.Equals('\n'));

b.Rows = cRows == 0 ? 1 : cRows;
}
}

Posto che nella cella [3] vi sia il controllo di cui noi dobbiamo estendere l'altezza.

martedì 8 marzo 2011

GridView non esegue refresh dopo Delete.

Oppure in inglese GridView does not refresh after delete command.

Ho letto in molti siti e in molti blog che questa situazione si verifica in parecchi casi e nei più disparati.
OGNI CASO HA UNA SUA SOLUZIONE e hai me non esiste una soluzione che calzi per tutti i casi, questo perchè (e per fortuna ) ogniuno di noi scrive il codice a suo modo.

Il mio caso

Web user Control

update panel
gridView (con template command)
objectDataSource (con metodi Insert Update Delete)

in questa configurazione...

<asp:UpdatePanel ID="updUpdate" runat="server" UpdateMode="Conditional">



<asp:GridView ID="grvGridView" runat="server" AllowSorting="True"

AutoGenerateColumns="False"

DataKeyNames="IDofMyTable"

DataSourceID="odsMYTable"

onrowdatabound="grvGridView_RowDataBound"

onrowdeleting="grvGridView_RowDeleting"

onrowupdating="grvGridView_RowUpdating"

>



<Columns>

<asp:TemplateField ShowHeader="False">

<EditItemTemplate>

<asp:LinkButton ID="btnUpdate" runat="server" CausesValidation="True" CommandName="Update"

Text="Update" />

<asp:LinkButton ID="BtnCancel" runat="server" CausesValidation="False" CommandName="Cancel"

Text="Cancel" />

</EditItemTemplate>

<ItemTemplate>

<asp:LinkButton ID="BtnEdit" runat="server" CausesValidation="False" CommandName="Edit"

Text="Edit" />

<asp:LinkButton ID="btnDelete" runat="server" CausesValidation="True" CommandName="Delete"

Text="Delete"

/>

</ItemTemplate>

<ItemStyle HorizontalAlign="Center" CssClass="selectButton" Width="70px"/>

</asp:TemplateField>

...

</Columns>



<asp:ObjectDataSource ID="odsMYTable" runat="server"

SelectMethod="SelectAll" TypeName="PrimaryDataSetTableAdapters.MYTable"

UpdateMethod="UpdateRow"

DeleteMethod="DeleteRow" InsertMethod="Insert" >

<InsertParameters>

...

</InsertParameters>

<DeleteParameters>

<asp:Parameter DbType="Guid" Name="IDofMyTable"/>

</DeleteParameters>

<UpdateParameters>

...

</UpdateParameters>

</asp:ObjectDataSource>


Ora vediamo gli eventi ...

protected void grvGridView_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
//
// set key parameters to param
// e.keys[0].value
//
odsMYTable.DeleteParameters["IDofMyTable"].DefaultValue = e.Keys[0].ToString();

odsMYTable.Delete();
}


protected void grvGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//
// set value to all field and
// set key parameters to param
// e.keys[0].value
//
odsMYTable.Update();
}


Questo per me ha funzionato, ma come anticipavo non esistono casi del tutto simili.

E' possibile che questa "situazione" si sia risolta per la rimozione di alcuni parametri dal Object data source generati in automatico da Ms.

giovedì 3 marzo 2011

Pdf su IE e FF senza problemi.

xBrowsing che brutta cosa...
E' un argomento esteso, che il più delle volta comporta tanto tempo e tanta pazienza e soprattutto buone doti di spirito di adattamento.

Sappiate sempre che ogni volta che fate un sito in HTML e riuscite a vederlo perfettamente uguale con IE e con FF vuol dire che :
a) non avete messo tag fra body e /body
b) siete stati davvero bravi ...

Tuttavia questo esempio esula dall'html puro, si tratta di una modalità concreta di come pubblicare sul vostro sito un pdf in modo che questo sia "pluggabile" con IE e con FF.

<!--[if IE]>
<div style="width:300px;height:300px; float:left;margin:25px;">
<span>Stai usando ie per vedere questo pdf</span>
<embed type="application/x-pdf"
height="100%" width="100%"
src ="mioPdf.pdf">
</embed>
</div>
<![endif]-->
<!--[if !IE]> <!-->
<div style="width:300px;height:300px; float:Left;margin:25px;">
<span>Stai usando qualche altro browser</span>
<object type="application/pdf"
height="100%" width="100%" data="mioPdf.pdf">
</object>
</div>
<!--<![endif]-->

L'esempio è stato fatto con IE 8 e con FF 3.5