Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

Una view ( questa volta persistente) per le nostre custom collection

Qualche giorno fa ho scritto un piccolo post per cominciare a prendere in considerazione l'idea di poter avere diverse view di una nostra custom collection. Giustamente, Corrado ha osservato che sebbene avessi creato una classe FaultCollection ed una corrispondente FaultCollectionDefaultView, c'è comunque un grande accoppiamento fra le due. Una non vive senza l'altra e questo rende il mio codice poco riutilizzabile: se voglio creare un'altra view, posso, però devo ricompilare e così via. Insomma, volevo migliorare un po' le cose e questa sera ho fatto i primi passi.

L'idea è innanzitutto quella di fornire alla classe FaultCollection una classe gemella che fornisce le informazioni sul binding. Questa classe non è più cablata in modo rigido nel codice, ma può essere cambiata via codice in un secondo momento in base alle esigenze. La classe FaultCollection espone quindi una proprietà View di tipo ITypedList che per default è FaultCollectionDefaultView.

public class FaultsCollection : BindingList<Fault>, ITypedList
{
    
private ITypedList _view = new FaultCollectionDefaultView();

    
public ITypedList View
    {
        
get return (_view); }
        
set { _view = value; }
    }

    
#region ITypedList
    public 
PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
    {
        
return (_view.GetItemProperties(listAccessors));
    }
    
public string GetListName(PropertyDescriptor[] listAccessors)
    {
        
return (_view.GetListName(listAccessors));
    }
    
#endregion
}

Detto questo, ho creato una seconda classe che implementa l'interfaccia ITypedList, chiamata FaultCollectionPersistentView. La caratteristica di questa classe è che permette di serializzare su file l'elenco delle proprietà, in modo tale da mantenerle tra una sessione di lavoro e l'altra.

public class FaultCollectionPersistentView : ITypedList
{
    
private string[] _fieldNames = { "When", "Reason", "Gravity", "Consequence" };
    
private const String FILENAME = "DisplayCache.txt";
    IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForAssembly();
}

La classe FaultCollectionPersistentView serializza sul file DisplayCache.txt l'ordine delle proprietà mostrate dalla classe Fault su un controllo DataGridView. L'ordine di default è quello indicato dalla variabile privata _fieldNames. Il metodo GetItemProperties (necessario per l'interfaccia ITypedList) questa volta è un po' più intelligente: se il file DisplayCache.txt esiste, allora lo legge ed ordina le proprietà in base a quello, altrimenti utilizza l'ordine di default indicato prima.

public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
    PropertyDescriptorCollection ret;

    Type tp = 
typeof(Fault);
    PropertyDescriptorCollection m_OriginalList = TypeDescriptor.GetProperties(tp);

    
if (isoFile.GetFileNames(FILENAME).Length == 0)
    {
        ret = m_OriginalList.Sort(_fieldNames);
        saveColumnsOrder();
    }
    
else
    
{
        _fieldNames = loadColumnsOrder();
    }
    
    ret = m_OriginalList.Sort(_fieldNames);
    ret.Remove(m_OriginalList.Find("ID", 
true));
    
return (ret);
}

La classe utilizza due metodi privati saveColumnsOrder e loadColumnsOrder per, rispettivamente, serializzare e deserializzare la variabile membro privata _fieldNames. Giusto per pulizia o a scopi di debug, ho creato questo metodo pubblico:

public void DeleteDisplayCache()
{
    isoFile.DeleteFile(FILENAME);
}

che non fa altro che cancellare il file di cache che uso per salvare le informazioni che mi servono.

Intercettare il reordering delle DataGridColumn di una DataGridView
Passiamo a manipolare l'interfaccia utente. Quando l'utente riordina a suo piacimento le colonne di una DataGridView, il framework solleva l'evento ColumnDisplayIndexChanged che possiamo intercettare e gestire a piacimento. Nel mio caso, quindi:

private void grdFaults_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e)
{
    ((FaultCollectionPersistentView)player.Faults.View).SaveColumnsOrder();
}

Queste è codice davvero brutto, brutto, brutto, che però ho scritto giusto per fare debug e vedere che tutto funzionasse. In pratica, chiamo un metodo pubblico SaveColumnsOrder che rileva il nuovo ordine delle colonne e chiama successivamente il metodo privato saveColumnsOrder descritto prima. Voglio assolutamente migliorare questa cosa, perchè castare sempre e comunque a FaultCollectionPersistentView è una follia, dato che abbiamo discusso prima il fatto che potrei interscambiare le classi per poter avere diverse view di una stessa custom collection.

powered by IMHO 1.3

Print | posted on Sunday, June 4, 2006 10:30 PM | Filed Under [ Tecnologia ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET