aprile 2006 Entries
Come metto la graffa su String.Format ?

Sto facendo alcuni esperimenti estendendo il class designer di Visual Studio (se avrò successo ne parlerò in un prossimo post) e mi son trovato nella necessità di inserire delle parentesi graffe all'interno di una String.Format. Visto che alle volte la soluzione può non essere banale, vi segnalo questa piccola FAQ di Brad Abrams che ho scovato e che magari può essere utile.

Ciao

powered by IMHO 1.3

Add Comment Filed Under [ .Net 2.0 ]
[OT] LOL, dopo il telefonino Nokia gratis...

Oggi mi è arrivata questa mail:

 Buongiorno a tutti, ho appena ricevuto quest'email. Non cestinatela dateci
un'occhiata, altrimenti potreste ritrovarvi a pagare st'estate una bolletta
in + quella di msn. Ho un avvertimento per tutti quelli che non hanno voglia
di buttare i propri soldi dalla finestra. Nell'estate del 2006, vi faranno
pagare per utilizzare MSN ed il conto e-mail se non hai inviato questo
messaggio almeno a 18 persone sulle nostre liste di contatti. Non è uno
scherzo e se non mi credete andate sul sito(
www.msn.com) e vedrete anche
voi.Quando avrete mandato questo messaggio ad un minimo di 18contatti il
vostro omino MSN diventerà blu. Per favore copiare e incollare questo
messaggio,non trasferirlo,perché altrimenti le persone non prenderanno sul
serio questa e-mail.

Ora, mi chiedo: ma è veramente possibile che la gente creda a 'ste robe? E considerando il fatto che chi me l'ha inviata, l'ha spedita ad una 30ina di persone, sono costretto a rispondermi affermativamente. Incredibile!

powered by IMHO 1.3

3 Comments Filed Under [ Off topic ]
Crad's Actions on CodeProject

I recently published an article about Crad's Actions on CodeProject. You can read it and send me feedbacks following this link

powered by IMHO 1.3

Add Comment Filed Under [ Crad's Actions ]
E le Actions se ne vanno su CodeProject

Nei giorni scorsi ho ricevuto un feedback da un ceco (nel senso che abita in Repubblica Ceca ) che aveva scovato la mia piccola libreria per puro caso, dicendo che secondo lui avrei dovuto metterla in un posto che le garantisse una maggiore visibiltà.

Io e il mio inglese maccheronico ci siam messi al lavoro e ho partorito un articoletto per CodeProject. Che dire, ricevere i primi rating positivi è una soddisfazione grandissima! Ora spero anche in qualche feedback in modo da poter evolvere il lavoro sin qui svolto.

powered by IMHO 1.3

Attenti alla proprietà DesignMode

Chi sviluppa componenti con supporto al designer di VisualStudio, sicuramente si è trovato ad utilizzare la proprietà DesignMode per verificare se il codice sia in esecuzione nel contesto del designer o a runtime.

Bene, avevo un problema che mi ha portato ad indagare su come funzioni internamente questa proprietà. Reflector alla mano ho scoperto che, in un Component...

protected bool DesignMode
{
    
get
    
{
        ISite site1 = 
this.site;
        
if (site1 != null)
            
return site1.DesignMode;
        
        
return false;
    }
}

Ora... premesso che, se utilizziamo VisualStudio, a design time il field site è un'istanza di System.ComponentModel.Design.DesignerHost.Site e che quel site1.DesignMode ritorna sempre true, c'è da fare un'importante considerazione: durante l'esecuzione del costruttore del Component, DesignMode è SEMPRE false, perché il corrispondente Site non è stato ancora assegnato.

Inutile dire che ci ho sbattuto il muso poche ore fa , ma senza averlo fatto magari non sarei venuto a conoscenza di questa sfumatura!

powered by IMHO 1.3

SetCompatibleTextRenderingDefault: cusa l'è?

Sicuramente tutti voi avrete notato che, nel template utilizzato da VS2005 per il metodo main dei nostri progetti windows forms, c'è una riga che recita

Application.SetCompatibleTextRenderingDefault(false);

Di cosa si tratta? L'ho scoperto ieri sera, cercando di utilizzare anche in C# la classe WindowsFormsApplicationBase: è una nuova feature delle classi che ereditano da Control del Fx 2.0 e consiste nella capacità di utilizzare GDI piuttosto che GDI+ per il rendering del testo.

Come mai? Beh, GDI+ ha la peculiarità di avere API estremamente semplici da utilizzare, ma il buon vecchio GDI offre parecchi vantaggi, per esempio:

  • Il look dell'applicazione è più consistente con le varie altre dialogs del sistema operativo
  • C'è un migliore supporto per la localizzazione e per il rendering dei caratteri unicode
  • Il rendering è molto più veloce e può sfruttare anche l'accelerazione hardware

Per avvalersene bisogna, per l'appunto, invocare il metodo sopra citato con il parametro "false". Ultima nota, per chi sviluppa custom controls o utilizza l'OwnerDrawing: quando ci si trova a dover effettuare il rendering di un testo, in luogo dei metodi MeasureString e il DrawString dell'oggetto Graphics, bisogna utilizzare gli analoghi MeasureText e DrawText della classe TextRenderer.

Altre info si trovano a questo link e a quest'altro.

powered by IMHO 1.3

Rilasciata la versione 1.1 delle Crad's Actions

La piccola libreria open-source che sto realizzando si è appena evoluta: grazie al tempo libero che ho avuto durante queste vacanze, sono riuscito (in ritardo rispetto a quanto avevo previsto, purtroppo) a rilasciare la versione 1.1 delle Crad's Actions.

Le novità rispetto alla release precedente sono parecchie: intanto un sensibile refactoring del codice (come?!?! così presto?!? ), che ora è sensibilmente più ordinato e comprensibile, poi l'aggiunta di nuove proprietà (quali shortcut keys, tooltip, ecc.ecc...), infine la creazione di un corposo numero di Standard Actions (es. Cut/Copy/Paste e parecchie altre), numero che è destinato ad aumentare nei prossimi giorni

Per dimostrare il tutto, ho creato un banale editor RTF. Ispezionandone il codice ci si può rendere conto di come la gestione dei vari elementi dell'interfaccia utente si semplifichi molto utilizzando questa libreria. Se avete 1 minuto di tempo, dateci un'occhiata e fatemi sapere cosa ne pensate, ne sarei veramente onorato.

Manca solo una cosa... ah sì! il link . Clickate pure qui!

powered by IMHO 1.3

Crad's Actions 1.1 Released!

I've released a new version of Crad's Actions, in which all you saw in the previous one has been really improved. I've also built a simple demo application. Obviously, you are welcome to download both the library and the executable following this link!

powered by IMHO 1.3

Filed Under [ Crad's Actions ]
Quanto è difficile realizzare un DAL

Oggi in Microsoft, dopo la sessione di Andrea, chiacchieravo un po' con il simpaticissimo Janky ed è venuto fuori un concetto che forse a molti sembrerà scontato, ma che spesso non lo è: realizzare un buon Data Access Layer è qualcosa di *dannatamente* complesso. Ma tanto, eh!!

E l'aggravante è che, purtroppo, questa caratteristica è difficilmente identificabile da chi si avvicina per le prime volte alle metodologie di sviluppo object-oriented e all'utilizzo dei patterns (e, OVVIAMENTE, tale categoria comprende anche il sottoscritto): il primo pensiero è che basta buttar giù due query, utilizzare i resultset per costruire entity piuttosto che riempire DataSet ed è tutto fatto.

In realtà, secondo me, non è tutto così semplice: se sviluppo utilizzando un Domain Model, come ho già detto in un post precedente, lo faccio perché la complessità dell'applicazione lo richiede. Ed in questo caso, ad esempio

  • è necessario tener traccia delle modifiche che apporto alla mie entity finché queste sono in memoria (Unit of Work)
  • è necessario caricare i dati solo quando effettivamente ci servono (Lazy Load)
  • è necessario gestire in un certo modo le relazioni master-detail (se ci pensate, non è scontato dire che se dalla collection di dettagli della mia entity Fattura rimuovo un DettaglioFattura , le corrispondenti righe su DB devono essere eliminate, perché questa entity DettaglioFattura a conti fatti non ha subito alcuna modifica)
  • sarebbe bene evitare di restituire diverse istanze della stessa business entity (Identity Map)
  • dobbiamo gestire la concorrenza, il mapping, l'ereditarietà delle classi, ecc.ecc.ecc...

Dove voglio arrivare? Beh, voglio arrivare a dire che, a conti fatti, spesso e volentieri è assolutamente consigliabile avvalersi di un ORM per realizzare un buon DAL (facciamo "quasi necessario"?). Oltre a semplificarci di molto la vita, infatti, ci permettono di apprezzare in anticipo le caratteristiche che ho elencato qualche riga più in alto, imparando a conoscerle, a comprenderne le motivazioni ed evitando magari di renderci conto della loro necessità solo perché, dopo un po' che ci lavoriamo, ci ritroviamo ad avere un DAL fatto a mano che in realtà non funziona bene come ci saremmo aspettati.

powered by IMHO 1.3

2 Comments Filed Under [ Architettura ]
In partenza per i Community Days

In questi giorni sono stato parecchio preso con il mio progettino delle Crad's Actions, ho corretto alcune cosine, riordinato un po' il codice con un occhio all'espandibilità e implementato nuove funzionalità, credo di metter su una versione nuova nella serata di mercoledì, Wi-Fi dell'albergo permettendo

Già... albergo... eh sì! Questa sera, dopo una giornata in ufficio, si parte per Milano. Ho preparato i bagagli, sistemato il portatile e scaricato gli autovelox per il TomTom  Credo di essere pronto per questi Community Days. Sinceramente sono molto ansioso di conoscere qualcuno della community di UGI... che so... Andrea, se riuscirà a parlare, o Igor, con il quale ho scambiato parecchie chiacchiere ultimamente su Messenger. Seguirò la track web il giorno 12 e la extreme giovedì, sono sicuro che ci sarà tanto da imparare (capperi CINQUE SESSIONI DI LIVELLO 400!!! ) e che i due giorni di ferie saranno ben spesi! E se pensiamo che tutto questo ben di Dio è assolutamente gratis, non posso che dire un gigantesco grazie in anticipo agli organizzatori e a tutti gli speaker: dev'essere un impegno immenso dar vita ad un evento del genere e credo che il loro sforzo sia encomiabile. Farne parte anche da semplice spettatore, mi inorgoglisce ancora di più!

Quindi, che dire... ci vediamo a Segrate, auguratemi buon viaggio

powered by IMHO 1.3

Add Comment Filed Under [ Off topic ]
Come far sapere ad un Component chi lo ospita?

Il titolo non sarà la massima espressione di linguaggio tecnico, però è un problema che mi sono trovato ad affrontare nel weekend sviluppando le mie Actions

Ora, chi le ha scaricate e magari ha avuto modo di guardarne i sorgenti, sa che si tratta di oggetti che ereditano da Component e che vanno sistemati su una Windows Form. Mi sono trovato nella necessità di avere, nella mia ActionList, un riferimento alla Form su cui essa giace. Requisito fondamentale: tutto deve essere "trasparente" all'utente, senza cioé richiedere che qualcuno si metta lì ad impostare chissà che proprietà.

Mi è subito sembrato un problema non proprio banale, meno male che ad un certo punto ho avuto l'illuminazione: "Caspita, ho usato mille volte ErrorProvider che visualizza icone su una Form. Dovrà pur avere un riferimento! Vediamo un po' come fa!".

Reflector alla mano, ho scoperto che in realtà il procedimento non è dei più complessi: basta effettuare l'override della proprietà Site che, tra le varie cose, permette di risalire al ContainerControl del componente. Come? Così:

private ContainerControl containerControl;
public ContainerControl ContainerControl
{
    
get return containerControl; }
    
set { containerControl = value; }    
}

public override ISite Site
{
    
get
    
{
        
return base.Site;
    }
    
set
    
{
        
base.Site = value;
        
// Questo è il codice che "does the trick!"
        
if (value != null)
        {
            IDesignerHost host1 = 
value.GetService(typeof(IDesignerHost)) as IDesignerHost;
            
if (host1 != null)
            {
                IComponent component1 = host1.RootComponent;
                
if (component1 is ContainerControl)
                {
                    
this.ContainerControl = (ContainerControl)component1;                            
                }
            }
        }
    }
}

Ora non mi dilungherò molto sulla funzione della proprietà Site, dico solo che è utilizzata da Visual Studio a design time, ad esempio, per dotare ogni controllo di quella proprietà (Name), scritta tra parentesi. Ciò che facciamo è, quando il designer ne setta il valore, risalire al RootComponent che lo hosta e settare opportunamente la proprietà ContainerControl. Quest'ultima è una proprietà public e, come tale, viene serializzata dal generatore di codice di Visual Studio. Risultato? Nella InitializeComponent della Form su cui abbiamo messo il nostro componente, troviamo una bellissima riga di codice simile alla seguente:

this.myComponent.ContainerControl = this;

Piccola considerazione: quando sviluppo custom controls/components, incontro spesso problemi che rischiano di farmi perdere parecchio tempo su Google alla ricerca di una soluzione. Bene, spesso la soluzione è già lì, nel mio hard disk, nascosta da qualche parte tra le n-mila classi del Framework. Morale: credo che Reflector sia un tool indispensabile per ogni sviluppatore e permetta di imparare (e capire) veramente tanto.

powered by IMHO 1.3

Creare un custom CollectionEditor

Quando creiamo CustomControls, spesso esponiamo proprietà che ritornano collection di items. Visual Studio è abbastanza furbo da generare un Designer opportuno per creare le istanze degli oggetti contenuti a design-time, tramite l'UITypeEditor CollectionEditor.

L'abbiamo usata migliaia di volte, si fa click su "Add" e, detto T il tipo base di dati esposto dalla collection, automaticamente una nuova istanza di T viene aggiunta ad essa. Bene, ma se T fosse un tipo astratto? o se volessimo popolare tale collection anche con tipi derivati da T? come farlo a design time? Nulla di più semplice! Basta creare un custom UITypeEditor che derivi da CollectionEditor ed eseguire l'override del metodo CreateNewItemTypes restituendo un array di Type che vogliamo supportare:

internal class MyCustomCollectionEditor: CollectionEditor
{
    
public MyCustomCollectionEditor()
        :
base(typeof(MyCustomCollection))
    {
        
/* MyCustomCollection è la custom collection di cui
           stiamo creando un nuovo UITypeEditor */
    
}
    
    
protected override Type[] CreateNewItemTypes()
    {
        
return new Type[] { typeof(ItemType1), typeof(ItemType2),
            
typeof(ItemType3) };
    }
}

Associamo questo nuovo editor alla collection che vogliamo gestire

[Editor(typeof(MyCustomCollectionEditor), typeof(UITypeEditor))]
public class MyCustomCollection: List<ItemBase>

  
// ....more code here....
}

ed il gioco è fatto: ora possiamo scegliere che tipo di item inserire!

powered by IMHO 1.3

Action's tutorial

I wrote a simple tutorial on how to use Crad's Actions in Visual Studio. You can read it here.

Filed Under [ Crad's Actions ]
Ancora sulle actions: come utilizzarle?

Dato che mi è stato chiesto da qualcuno in mail, ho pubblicato un breve tutorial (in inglese, spero non troppo maccheronico ) su come utilizzare le Actions per .NET 2.0.

Per leggerlo basta un click qui!

powered by IMHO 1.3

Et voilà! Le actions di Delphi su .NET 2.0!

Chi ha lavorato in Delphi sa quanto siano comode le actions! Di cosa si tratta? Allora...

Una form, solitamente, permette di compiere la stessa azione tramite più elementi visuali; pensate ad esempio alla funzione "Grassetto" in un ipotetico editor RTF: magari possiamo attivarla tramite menu, oppure potremmo utilizzare una comoda toolbar, o ancora potremmo accedervi tramite un bel context menu. Tutti questi elementi condividono parecchie proprietà: innanzitutto devono tutti rispondere al click del mouse allo stesso modo, e questo si può già fare in .NET assegnando lo stesso event handler a tutti gli oggetti per i rispettivi eventi click. Purtoppo ciò non sempre basta: è necessario, ad esempio, che tutti questi elementi siano simultaneamente Checked o Uncheck, e lo stesso dicasi per la proprietà Enabled/Disabled, è necessario che presentino lo stesso testo (se applicabile) e che visualizzino la medesima immagine.

Bene, le Crad's Actions fanno tutto questo, o ci provano, visto che le sto ancora sviluppando , però qualche risultato già si vede (per quello che un'immagine statica può rendere...). Ve piase l'idea? Bene, allora se la cosa vi interessa, trovate i sorgenti qui!

ActionsDemo

powered by IMHO 1.3

Un file di log con Notepad

Giuro che questa non la sapevo! Chissà se esistono altre features nascoste di questo tipo!

powered by IMHO 1.3

One Comment Filed Under [ Misc ]
Quando si viene scovati da Google

Oggi, in un un momento di pausa, ho dato un'occhiata ai referrers di questo blog. Ora, magari per tantissimi di voi sarà normale, ma giuro che non mi aspettavo di vedere che qualcuno è arrivato su queste pagine dopo aver cercato ITypedList o Custom Attributes su Google, e la cosa ha suscitato in me parecchia emozione.

Un motivo in più per impegnarmi a scrivere post il più possibile interessanti, sperando sempre che possano risultare utili a qualcuno, come tanti altri post letti su UGI (e su altre dimore) lo sono stati per me.

powered by IMHO 1.3

Add Comment Filed Under [ Off topic ]
Regola aurea per chi usa Value Types

I ValueTypes sono oggetti un po' particolari: sono allocati nello stack piuttosto che nel managed-heap e le assegnazioni, se effettuate con reference type, danno luogo a quel meccanismo che risponde al nome di boxing/unboxing. Dicevo, regola aurea: *MAI* introdurre metodi che cambiano lo stato interno di un value type, i risultati potrebbero essere "strani"

Click sul titolo per continuare a leggere!

2 Comments Filed Under [ .Net 2.0 ]