giovedì 2 giugno 2011

Columns Custom Attribute e GridView

Nell'ottica di realizzare un modello di CRUD completamente dinamico linkato ai dati tramite List T mi sono imbattutto nel classico problema " già ma come associo un nome civile alle colonne di una dataTable?"

Ho fatto quindi qualche prova sfruttando i custom attribute, che si sono rivelati ottimi accessibili e per nulla complessi da usare. Certo è vero che come per tutte le cose esagerare non serve a rendere il proprio codice migliore, a volte lo rende più illegibile.

Partiamo quindi dalla classe CUSTOM ATTRIBUTE.


[
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 bool _isVisibile;
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 bool isVisibile
{
get { return _isVisibile; }
}

public DbMapperAttribute(
int ColumnOrder,
string DbFieldName,
string MappingEntity,
string HeaderOrCaption,
bool IsVisible)
{
_dbFieldName = DbFieldName ;
_mappingEntity = MappingEntity;
_headerOrCaption = HeaderOrCaption;
_isVisibile = IsVisible;
_columnOrder = ColumnOrder;
}
}


System.AttributeUsage( AttributeTargets.Class| AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)

Di tutto quello che ho scritto questa è la cosa importante almeno quando lo è la using di
System.ComponentModel che quin non è menzionata.

Ora direi che è il momento di vedere l'entity e come questa subisce l'effetto
del custom Attribute.


[DbMapper(1,"IDEntita", "IDPrototipoEntita", "Id", true)]
[DbMapper(2,"NomeEntita", "NomePrototipoEntita", "Entità",true)]
[DbMapper(3,"DescrizioneEntita", "DescrizionePrototipoEntita", "Descrizione",true)]
public class Entita
{
private int _IDEntita;
private string _NomeEntita;
private string _DescrizioneEntita;

public int IDEntita
{
get { return _IDEntita; }
set { _IDEntita = value; }
}
public string NomeEntita
{
get { return _NomeEntita; }
set { _NomeEntita = value;}
}
public string DescrizioneEntita
{
get { return _DescrizioneEntita; }
set { _DescrizioneEntita = value; }
}
}


E' importante che gli attributi vadano nell'intestazione della classe e non sulle singole proprietà
perchè e lo capiremo a breve, in questo modo sarà molto più semplice accedere agli attributi stessi.

Quindi posto di aver realizzato un proprio Generatore di colonne, pre DataBound (ossia
una sub che richiamerete prima ... )
All'interno è necessario implementare una logica non troppo differente da questa.

System.Attribute[] attrs = System.Attribute.GetCustomAttributes(modelPrototype);

foreach (System.Attribute attr in attrs)
{

if (attr is DbMapperAttribute)
{
DbMapperAttribute dma = (DbMapperAttribute)attr;

BoundField dcf = new BoundField();

dcf.HeaderText = dma.headrOrCaption;
dcf.DataField = dma.dbFieldName;
dcf.SortExpression = dma.dbFieldName;

grvItemsCollection.Columns.Add( dcf);
}
}

In questo modo sarete sempre sicuri di avere le vostre colonne ben Nominate.

Nell'esempio ho specificato altri parametri che possono dar vita e vigore alla fantasia di ogniuno di noi, come l'implementazione dell'ordine d'apparizione, oppure se visibile o no..

Verosimilmente non sarà complesso aggiungere anche il tipo

In questo modo sfruttando un unico controllo ( ben fatto e ben gestito ) si può sfruttare il codice
tante volte quante lo si vuole... !

Nessun commento: