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.

Nessun commento: