<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Esame 70-526</title>
        <link>http://blogs.ugidotnet.org/idamiani/category/Esame 70-526.aspx</link>
        <description>Serie di post sull'esame 70-526 per conseguire la certificazione MCPD</description>
        <language>it-IT</language>
        <copyright>Igor Damiani</copyright>
        <generator>Subtext Version 2.6.0.0</generator>
        <item>
            <title>Ed invece il mio esame 70-526 &amp;egrave; sempre l&amp;igrave;...</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/02/19/71155.aspx</link>
            <description>E invece io non ce la faccio. Mi riferisco all'ottimo successo di Marco nell'esame 70-548. Sono fatto un po' diversamente, io. Ho i periodi in cui ho voglia di studiare per l'esame, ed altri in cui invece preferisco studiare altro, come WPF. E' un brutto difetto che mi trascino dietro...anche i miei post sull'esame 70-526 subiscono rallentamenti, ma non ci posso fare nulla. Anche ai tempi della scuola ero fatto così: se una cosa non mi appassiona almeno all'80%, tendo a dimenticarmene e ad accantonarla. Se aggiungete il fatto che il mio lavoro è fatto d'altro che .NET, allora si arriva rapidamente alla conclusione che studio e bloggo solo quando ho l'ispirazione e la voglia. Peccato. E' un brutto difetto, perchè magari quello che potrei fare in 15 giorni, me lo trascino dietro per un tempo indefinito. Magari potrei dare l'esame e superarlo, ma l'idea di piantare lì i post non mi piace: preferisco dare precedenza alla community e quindi la morale è "Non dare l'esame fino a quando non finisci di bloggare tutti gli argomenti per l'esame!".  In fondo...&amp;lt;cit&amp;gt;...siamo solo umani...&amp;lt;/cit&amp;gt;&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/71155.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/02/19/71155.aspx</guid>
            <pubDate>Mon, 19 Feb 2007 18:49:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/02/19/71155.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/71155.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/71155.aspx</trackback:ping>
        </item>
        <item>
            <title>[70-526, #8] Ancora sulla stampa: anteprima e note veloci sulla sicurezza</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/02/05/69828.aspx</link>
            <description>Già ai tempi dell'esame 70-316, avevamo visto gli strumenti che il FW2.0 ci mette a disposizione per produrre anteprime di stampa dei nostri documenti PrintDocument. Attraverso la classe PrintPreviewDialog, abbiamo a disposizione una Windows Form che mostra l'anteprima di stampa del nostro documento. Questa Windows Form non è modificabile: così è, e così ce la teniamo. Come tutte le WF, per visualizzarle non dobbiamo fare altro che chiamare il metodo ShowDialog, solo dopo aver impostato la proprietà Document sull'istanza di PrintDocument di cui vogliamo generare l'anteprima. La chiamata a ShowDialog scatena la stampa del documento, che però non viene indirizzata sulla stampante di default, bensì sulla finestra di dialogo, scatenando l'esecuzione dell'evento PrintPage per ogni pagina come abbiamo già visto precedentemente. La WF visualizzata dal PrintPreviewDialog possiede alcune caratteristiche particolari. Vediamole perchè ci torneranno utili più avanti:  La superficie della form è occupata per la maggior parte da un rettangolo bianco che mostra l'anteprima In alto a sinistra c'è una piccola toolbar, che ci consente di stampare il documento, di impostare lo zoom, di decidere quante pagine vogliamo vedere alla volta (1, 2, 3, 4 e 6) e di chiudere la finestra In alto a destra c'è un controllo NumericUpDown che ci permette di scorrere le pagine che compongono il documento Il controllo PrintPreviewControlCon il FW2.0 c'è una possibilità in più. Grazie all'implementazione della classe PrintPreviewControl, infatti, possiamo creare una finestra di anteprima custom, personalizzandola e aggiungendo features come desideriamo noi. Il "rettangolo bianco" di cui ho parlato al punto (1) non è nient'altro che un controllo PrintPreviewControl, che renderizza un PrintDocument. Come tutti i controlli, anche questo deve essere posizionato su una Windows Form normalissima, che quindi possiamo disegnare come vogliamo noi. PrintPreviewControl espone alcune proprietà che ci permettono di emulare il comportamento della WF standard mostrata da PrintPreviewDialog. Le proprietà sono:  la proprietà Document è la più importante: stabilisce quale PrintDocument mostrare nell'anteprima Columns e Rows permettono di stabilire quante pagine vedere nell'anteprima (rispettivamente in senso orizzontale e verticale) Zoom permette di stabilire lo zoom iniziale dell'anteprima StartPage permette di stabilire la pagina del PrintDocument da visualizzare la proprietà UseAntiAlias, come dice il nome stesso, renderizza i font con un effetto di anti-aliasing per migliorarne la leggibilità Agendo su queste proprietà, quindi, possiamo riprodurre tutte le funzionalità della dialog esposta da PrintPreviewDialog. Ma possiamo andare un po' più in là, aggiungendo features (controlli, per esempio) alla WF capaci di agire sul PrintDocument e di modificarne la stampa. La sicurezza - PrintingPermissionIl FW2.0 ci permette di regolare l'accesso alle stampanti da parte del nostro managed code, coinvolgendo la classe PrintingPermission, che eredita direttamente da CodeAccessPermission. Tale classe espone la proprietà Level, che assume i valori determinati dall'enum PrintingPermissionLevel&amp;nbsp;(AllPrinting, DefaultPrinting, NoPrinting e SafePrinting). La classe PrintingPermission dispone oltre agli altri dei metodi Assert e Demand. Vi consiglio una lettura agli articoli su MSDN intitolati Security Permissions&amp;nbsp;e Requesting Permissions.&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/69828.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/02/05/69828.aspx</guid>
            <pubDate>Mon, 05 Feb 2007 15:44:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/02/05/69828.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/69828.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/69828.aspx</trackback:ping>
        </item>
        <item>
            <title>[70-526, #7] Stampare con il Framework 2.0</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/01/29/69026.aspx</link>
            <description>E' talmente tanto che uso Reporting Services di SQL Server 2005 che ho spazzato dalla mia mente tutto quello che ho studiato per il 70-316. Ma è bastato un esercizio di auto-ipnosi regressiva per ricordare tutto quello che c'è da sapere - ovviamente, sto scherzando. Le classiQuando si&amp;nbsp;tratta di stampare con il FX2.0, dobbiamo focalizzare la nostra attenzione su una manciata di classi: PrintDocument, che rappresenta un documento da stamparePrintDialog, che rappresenta la dialog standard per scegliere la stampante su cui inviare l'outputPrintPreviewDialog, che permette di mostrare all'utente una finestra per l'anteprima di stampaPageSetupDialog, che permette all'utente di impostare margini, orientamento e stampante Il più importante di tutti è il PrintDocument, che è il documento vero e proprio e spesso è un input per le altre dialog elencate sopra. Prima di poter utilizzare i dialog standard di Windows, dobbiamo quindi generare un documento e capire come impaginare il contenuto, come generare più pagine e così via. Creare un oggetto PrintDocument implica la buona conoscenza di GDI+, perchè ogni cosa renderizzata su un PrintDocument viene disegnata attraverso la classe Graphics e tutti i suoi metodi. La cosa più semplice che possiamo fare per cominciare a lavorare con un PrintDocument è quello di trascinarlo dalla Toolbox su una Windows Form. Il PrintDocument comparirà nella tray-area della WF stessa. Siccome però siamo sviluppatori, vediamo come fare tutto via codice, giusto per continuare a battere sulla tastiera e a dimenticare un po' il mouse. :-)  PrintDocument doc = new PrintDocument();
doc.BeginPrint += new PrintEventHandler(doc_BeginPrint);
doc.EndPrint += new PrintEventHandler(doc_EndPrint);
doc.PrintPage += new PrintPageEventHandler(doc_PrintPage);
doc.QueryPageSettings += new QueryPageSettingsEventHandler(doc_QueryPageSettings);

Per cominciare la stampa diretta sulla stampante di default di Windows, è sufficiente chiamare il metodo Print della classe PrintDocument. La chiamata a questo metodo non visualizza nulla, non c'è interazione con l'utente. Il FX usa il PrintDocument, genera il contenuto per ciascuna pagina e stampa.
La classe PrintDocument espone 4 importanti eventi. BeginPrint viene sollevato all'inizio della stampa, prima che la prima pagina venga stampata. EndPrint viene sollevato al termine della stampa. PrintPage e QueryPageSettings vengono sollevati ad ogni pagina: il primo viene sollevato quando occorre generare il contenuto della pagina per l'invio alla stampante. QueryPageSettings viene sollevato prima ancora di PrintPage, e permette di impostare un particolare formato per ciascuna pagina (orientamento, margini e così via).
Il più importante fra questi è indubbiamente PrintPage. Il parametro PrintPageEventArgs permette di ottenere un riferimento a Graphics, attraverso&amp;nbsp;il quale possiamo disegnare testo, grafica e così via. Questa classe espone alcune proprietà essenziali per la gestione della stampa:&amp;nbsp;possiamo impostare la&amp;nbsp;proprietà Cancel&amp;nbsp;a false per annullare il processo di stampa, possiamo impostare HasMorePages&amp;nbsp;a true per indicare che ci sono ancora pagine da stampare. Difatti, l'evento PrintPage viene continuamente chiamato fintantochè HasMorePages&amp;nbsp;continua a valere true. La proprietà PageBounds&amp;nbsp;rappresenta la dimensione totale della pagina su cui si sta stampando, mentre MarginBounds&amp;nbsp;considera anche eventuali margini della pagina stessa. La proprietà PageSettings&amp;nbsp;consente l'accesso a tutta una serie di informazioni sulla pagina corrente (Bounds, Margins, PaperSize, PrintableArea, PrinterResolution).
Per un esempio più pratico e per maggiori informazioni, rimando al mio vecchio post sull'esame 70-316.
In breve, la classe PrintPreviewDialogSe volessimo mostrare un'anteprima di stampa, possiamo utilizzare il componente PrintPreviewDialog. Per utilizzare, non dobbiamo fare altro che impostare la proprietà Document su un oggetto PrintDocument valido. La chiamata al metodo ShowDialog&amp;nbsp;mostra l'anteprima, scatenando prima gli eventi relativi al PrintDocument di cui abbiamo discusso prima.&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/69026.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/01/29/69026.aspx</guid>
            <pubDate>Mon, 29 Jan 2007 13:16:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/01/29/69026.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/69026.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/69026.aspx</trackback:ping>
        </item>
        <item>
            <title>980 birre medie</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/01/26/68689.aspx</link>
            <description>Un certo tizio stasera&amp;nbsp;offrirà 980 birre medie. Non chiedetemi chi le deve bere (io una di sicuro), prendetelo più come un abbonamento a lunga scadenza. :-) Complimentissimi a un certo tizio. :-D A proposito, mi aspetto un commento, altrimenti qua vengo preso per pazzo!&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/68689.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/01/26/68689.aspx</guid>
            <pubDate>Fri, 26 Jan 2007 11:32:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/01/26/68689.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/68689.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/68689.aspx</trackback:ping>
        </item>
        <item>
            <title>[70-526, #6] Carrellata: ToolTip, ProgressBar ed HelpProvider</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/01/15/66888.aspx</link>
            <description>Oggi pensiamo ad un post dai contenuti leggeri, affrontando l'utilizzo di controlli semplici ed efficaci da poter usare sulle nostre Windows Forms. L'esame 70-526 ci chiede di utilizzare i controlli ToolTip, ProgressBar, HelpProvider e&amp;nbsp;ErrorProvider. Per quest'ultimo vi rimando, oltre che ai vari links&amp;nbsp;ufficiali Microsoft,&amp;nbsp;al mio stesso post scritto un po' di tempo fa relativamente all'esame 70-316: nel FW2.0 da questo punto di vista non è cambiato nulla, per cui... Per gli altri controlli, continuate a leggere. Componente&amp;nbsp;ToolTipIl controllo ToolTip è in realtà un componente, e serve a mostrare per l'appunto un piccolo tooltip sui controlli. Lo si trascina dalla toolbox di VS2005 su una qualsiasi Windows Forms del nostro progetto. Il componente finisce nella tray-area della WF, dove possiamo settarne la proprietà principali. ToolTip implementa l'interfaccia IExtenderProvider (che prevede l'implementazione del solo metodo CanExtend): ciò significa che, banalmente, il ToolTip non fa nulla da solo, ma aggiunge alcune proprietà ai controlli presenti sulla Windows Forms stessa. Nella tray-area definiamo proprietà generiche - come l'aspetto visivo - del componente Tooltip, ma il contenuto vero e proprio&amp;nbsp;viene definito sul controllo che fa uso del tooltip. Vediamo di spiegarci meglio, dando un'occhiata alle proprietà del componente Tooltip; le principali sono:  Active, che attiva o meno la visualizzazione dei tooltip BackColor&amp;nbsp;e ForeColor, che determinano il colore di sfondo e del testo dei tooltip IsBalloon, che determina se i tooltip devono apparire come dei ballon ToolTipIcon, che determina un'eventuale icona ToolTipTitle&amp;nbsp;serve per indicare un titolo che deve apparire nei tooltip UseAnimation&amp;nbsp;e UseFading&amp;nbsp;determinano se il tooltip deve apparire con un'animazione e se deve scomparire con un fade out Dopo aver configurato il ToolTip, proviamo a selezionare un qualsiasi altro dei controlli sulla Windows Forms (Button, TextBox, ListBox e via dicendo). A tutti questi controlli è stata aggiunta una proprietà di tipo stringa, che determina quindi il contenuto effettivo del tooltip per quel specifico controllo che abbiamo selezionato. Il ToolTip espone l'evento Draw&amp;nbsp;che possiamo gestire con un opportuno event handler per intercettare il disegno del tooltip da parte del framework. L'event handler fa uso della classe DrawToolTipEventArgs, che espone un'istanza di Graphics e Font, per esempio, che possiamo sfruttare per customizzare l'aspetto del ToolTip. Controllo ProgressBarDirei che questo controllo non ha bisogno di presentazioni, giusto? :-) Esisteva fin dai tempi di Visual Basic 3, probabilmente, ed inoltre è uno dei controlli che più mi stanno simpatici. La ProgressBar dà un'indicazione visuale dello stato di un'elaborazione più o meno lunga, informando l'utente a che punto siamo e quanto manca alla fine. Non in termini di tempo, è chiaro, ma relativamente parlando. Gran parte dell'interfaccia della ProgressBar è ereditata da Control, ovviamente, ma ne aggiunge qualcuna necessaria: Minimum&amp;nbsp;e Maximum&amp;nbsp;determinano il valore minimo e massimo che la proprietà Value&amp;nbsp;può assumere. In base a questi valori, il controllo si disegna in modo opportuno. Esempio banale: se Minimum = 0, Maximum = 100 e Value = 50, la ProgressBar disegnerà una barra che arriverà fino a metà del controllo. La proprietà Style&amp;nbsp;determina lo stile di questa barra, che può assumere i valori dell'enum ProgressBarStyle&amp;nbsp;(Blocks, Continuous e Marquee). Come potete ben immaginare, la ProgressBar viene soprattutto usata per notificare all'utente lo stato di un'operazione di lunga durata, per far capire che il vostro applicativo non si è impallato ma sta facendo quello che deve fare. Questo vuol dire utilizzarla quindi in combinazione con thread secondari oppure utilizzando il componente BackgroundWorker, di cui ho già parlato in passato per l'esame 70-536. Esame in cui ho preso un punteggio infimo.&amp;nbsp;Il&amp;nbsp;BackgroundWorker mi è rimasto in testa, al punto che ne ho scritto un articolo su uno dei numeri di IoProgrammo uscito nei mesi scorsi. Componente HelpProviderIl componente HelpProvider serve per fornire assistenza all'utente su una Windows Form. Si basa sulla classe Help che incapsula tutto l'engine per gestire help in formato HTML. Come il ToolTip, l'HelpProvider aggiunge un po' di proprietà ai controlli su una Windows Forms. Tali proprietà impostano le modalità di help che l'applicativo fornisce all'utente. Per testarlo velocemente e capirne il funzionamento, seguite i seguenti passi:  Aggiungete una nuova Windows Form al progetto Trascinate un HelpProvider dalla toolbox di VS2005 sulla WF Aggiungete una TextBox alla stessa WF Settate la proprietà HelpString della TextBox (aggiunta dall'HelpProvider) con la stringa: "Eccoti l'aiuto: guarda ed impara!" Eseguite il progetto. Quando la WF appare, date il focus alla TextBox e premete F1. Il FW2.0 fa apparire un tooltip (graficamente diverso dal classico ToolTip) che mostra la stringa impostata per quel controllo. Ovviamente, l'HelpProvider può essere sfruttato in modo più raffinato. Non si limita alla visualizzazione di semplici tooltip. La proprietà HelpNamespace&amp;nbsp;ci permette di impostare il file di help da utilizzare, che può essere in formato CHM o HTML. Ad ogni controllo possiamo quindi associare una keyword, che verrà ricercata come topic nel file di help.&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/66888.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/01/15/66888.aspx</guid>
            <pubDate>Mon, 15 Jan 2007 12:14:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/01/15/66888.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/66888.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/66888.aspx</trackback:ping>
        </item>
        <item>
            <title>[70-526, #5] Utilizzare la PropertyGrid</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/01/11/66034.aspx</link>
            <description>Anche se magari non ve ne rendete conto, utilizzate il controllo PropertyGrid&amp;nbsp;tutte le volte che premete F4 all'interno dell'IDE di Visual Studio 2005. La PropertyGrid non è nient'altro che il componente .NET che implementa la Property Window dell'IDE. La cosa interessante è che possiamo utilizzarla all'interno dei nostri progetti .NET. La PropertyGrid mostra tutte le proprietà di un oggetto managed nello stesso identico modo attuato dalla Property Window. E' sufficiente impostare la proprietà SelectedObject (o SelectedObjects&amp;nbsp;per più oggetti contemporaneamente) esposta da questo controllo. La PropertyGrid rifletterà automaticamente questa impostazione, mostrando le proprietà dell'oggetto. Attraverso l'interfaccia, possiamo personalizzarne e controllarne l'aspetto. La proprietà PropertySort&amp;nbsp;permette di impostare attraverso l'enum omonimo la modalità di visualizzazione che deve assumere la PropertyGrid (alfabetica, per categorie od entrambe), esattamente come accade nell'IDE. Le proprietà ViewBackColor&amp;nbsp;e ViewForeColor&amp;nbsp;permettono di impostare rispettivamente il colore di sfondo e del testo nella PropertyGrid. La proprietà CategoryForeColor&amp;nbsp;regola il colore del testo utilizzato nelle barre relative alla categoria. Una cosa importante: quando si cambia&amp;nbsp;una proprietà dell'oggetto referenziato da SelectedObject, il cambiamento non si riflette automaticamente nella PropertyGrid - per farlo, è necessaria una chiamata al metodo Refresh. Il metodo ExpandAllGridItems&amp;nbsp;espande automaticamente tutti gli elementi che possono essere espansi (leggesi: categorie oppure proprietà complesse, come Size, Location, Font&amp;nbsp;- tutte derivate da Control). Personalmente, ho utilizzato questo controllo all'interno di Happy Sign (adesso è stato rimosso) per consentire all'utente di cambiare le Signature senza troppe complicazioni, proprio perchè potete usare questo controllo con qualsiasi oggetto, compresi quelli del vostro domain model. Gli eventi della PropertyGridLa Property Grid espone un certo numero di eventi. Tra i più interessanti segnalo:  SelectedGridItemChanged, per reagire quando cambiamo riga (e quindi proprietà selezionata) all'interno della PropertyGrid SelectedObjectsChanged, per reagire quando cambia la proprietà SelectedObject PropertyValueChanged, per reagire quando cambiamo il valore di una proprietà all'interno della PropertyGrid L'evento SelectedGridItemChanged&amp;nbsp;utilizza la classe GridItem&amp;nbsp;che, per dirla come la dice MSDN, implements one row in a PropertyGrid. GridItem espone la proprietà Expandable, che ci dice se la riga può essere espansa per mostrare le subproperties della proprietà selezionata: questo accade, per esempio, quando selezioniamo Size, che espone Width ed Height. La trovo però una spiegazione non sufficiente, perchè Expandable ritorna true anche quando selezioniamo una categoria, per cui stiamo attenti. La proprietà Label&amp;nbsp;ci ritorna la caption della riga corrente, mentre Value&amp;nbsp;il valore della proprietà (intesa come object, com'è ovvio che sia). L'evento SelectedObjectsChanged non ha nulla di particolare da segnalare. L'evento PropertyValueChanged viene sollevato quando modifichiamo il valore di una proprietà. L'event handler, oltre al classico object sender a cui siamo abituati, utilizza la classe PropertyValueChangedEventArgs che espone il membro ChangedItem che non è nient'altro che il GridItem sul quale abbiamo fatto la modifica. La proprietà OldValue invece è un object che contiene il vecchio valore, prima della modifica. PropertyGrid? Conoscere&amp;nbsp;bene anche il namespace System.ComponentModel!Utilizzare la PropertyGrid senza conoscere un po' il namespace System.ComponentModel&amp;nbsp;è quasi inutile. Questo namespace contiene l'implementazione di un certo numero di classi&amp;nbsp;Attribute molto utili a questo scopo. Ricordo ancora (a grandi linee, non esageriamo) la sessione di Corrado datata 14 Luglio 2005, durante la quale si vedeva come creare Windows Control. Quel giorno vedemmo come creare Windows Control capaci di esporre/ordinare/organizzare le loro proprietà in modo efficiente. Le stesse logiche sono valide anche in questo contesto, ovviamente, perchè alla fin fine - come ho detto prima - la PropertyGrid è lo stesso identico controllo dell'IDE di VS2005. Per esempio, utilizzare CategoryAttribute&amp;nbsp;permette di posizionare una certa proprietà all'interno di una categoria di nostra scelta. L'attributo DefaultValueAttribute&amp;nbsp;permette di impostare il valore di default di una certa proprietà; alla PropertyGrid serve per sapere quando deve utilizzare il grassetto nell'indicare il valore stesso (e per sapere quando serializzare il codice nel nomeform.Designer.cs). DescriptionAttribute&amp;nbsp;serve per indicare una descrizione per una certa proprietà, che appare nella parte inferiore della PropertyGrid. In generale, quindi, tutto il meccanismo da studiare per costruire controlli per un certo grado di user-experience a design-time (editor custom per una determina proprietà) viene applicato anche con la PropertyGrid. Ricordiamoci che l'esame 70-526 ci tartassa anche sullo sviluppo di controlli per Windows Forms (sia da zero che ereditati da controlli .NET standard): sapere bene il System.ComponentModel&amp;nbsp;quindi non riguarda solo la PropertyGrid, ma può fare la differenza tra passare e non passare l'esame!&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/66034.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/01/11/66034.aspx</guid>
            <pubDate>Thu, 11 Jan 2007 16:18:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/01/11/66034.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/66034.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/66034.aspx</trackback:ping>
        </item>
        <item>
            <title>[70-526, #4] Leggere un documento XML con XmlReader</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/01/10/65780.aspx</link>
            <description>Al contrario di quanto abbiamo fatto nei due post precedenti (1 e 2), questa volta vedremo come aprire un documento XML in modalità read-only attraverso l'utilizzo della classe XmlReader. Questo oggetto non carica tutto il documento XML in memoria, ma fornisce un veloce reader forward-only&amp;nbsp;per leggere tutti i nodi del documento. Dimenticatevi quindi di poter saltare liberamente avanti ed indietro all'interno del documento: con XmlReader si guarda solo in avanti. :-) L'istanziazione passa attraverso un metodo statico Create, che dispone di ben 12 overload che permettono di leggere un documento da file, da uno Stream e&amp;nbsp;da un TextReader ed&amp;nbsp;utilizzando in certi casi un'istanza di XmlReaderSettings (vedere questo articolo per dettagli). Nel più semplice dei casi avremo quindi una chiamata come questa:  string xmlFilename = &amp;quot;E:\\Books.xml&amp;quot;;

using (XmlReader reader = XmlReader.Create(xmlFilename))
{ }

La classe XmlReader implementa l'interfaccia IDisposable, perciò, fate un favore ai bytes che compongono il vostro software (tutto compreso: dalle celle al CLR): includetela in un blocco using per rilasciare le risorse appena finito il lavoro con il vostro documento XML. :-)
Il file XML Books.xml a cui si fa riferimento è stato creato attraverso la classe XmlDocument di cui abbiamo già parlato ieri. Una volta istanziato e creato il reader XML, utilizziamo il metodo Read che salta di nodo in nodo addentrandosi in profondità nel grafo XML seguendone ovviamente la struttura. Il metodo Read ritorna false quando si è arrivati alla fine del documento; lo stesso risultato è esposto dalla proprietà EOF. Possiamo quindi implementare una banale iterazione che vada ad esplorare tutti i nodi del documento utilizzando un ciclo while, come riportato qui sotto:

while (reader.Read())
{ }

Ad ogni iterazione, l'oggetto reader espone tutte le informazioni relative al nodo corrente. La proprietà NodeType per esempio esprime attraverso un&amp;nbsp;enum XmlNodeType&amp;nbsp;il tipo del nodo corrente. La proprietà Depth ci dice a quale livello di profondità ci troviamo all'interno del documento XML. La proprietà HasAttributes&amp;nbsp;ci dice se il nodo corrente ha oppure no degli attributi.
Ovviamente, esplorare un documento XML senza poterne leggere il contenuto ha poco senso. A questo scopo, XmlReader espone una serie di metodi riconoscibili dal prefisso ReadElementContentAs + qualcosa, dove qualcosa vuol dire Int, Boolean, DateTime, String, Double, Float&amp;nbsp;e così via. In questo modo, evitiamo un casting che viene invece effettuato dal FW. In altre parole,&amp;nbsp;invece di essere letto come stringa, viene letto con il tipo di dato più coerente per il contesto.&amp;nbsp;Un esempio concreto: utilizzando sempre il documento XML mostrato qui, possiamo intercettare la lettura del tag &amp;lt;year&amp;gt;1998&amp;lt;/year&amp;gt; e salvare in un oggetto int il valore dell'anno.
string nodeName = reader.LocalName;
if (nodeName.Equals(&amp;quot;year&amp;quot;))
{
   year = reader.ReadElementContentAsInt();
   Console.WriteLine(&amp;quot;Anno : &amp;quot; + year.ToString());
}
Ho inserito questo blocco di codice nel ciclo while mostrato prima. Ad ogni iterazione, controllo il nome dell'elemento su cui mi trovo. Quando il nome del tag è "year", allora posso leggere il contenuto del tag direttamente castandolo ad intero. Esiste un metodo ReadElementContentAs per ogni tipo di dato, ovviamente. Possiamo eventualmente usare il metodo ReadElementContentAs&amp;nbsp;per leggere il contenuto di un tag specificando il Type corretto.
Al di là dello spostarsi nel documento con il metodo Read, possiamo utilizzare altri metodi più efficaci e più specifici in base al contesto. Se un certo elemento ha uno o più attributi, possiamo usare MoveToFirstAttribute&amp;nbsp;e MoveToNextAttribute. Non hanno bisogno di parametri, ritornano true se l'operazione ha avuto successo, altrimenti false. Il metodo MoveToAttribute&amp;nbsp;è un po' più selettivo: come parametri accetta in input un Int32 o una string&amp;nbsp;per indicare a quale attributo spostarsi.
Se volete skippare tutti i nodi fino a quando non ne trovate uno con un particolare tag, utilizzate il metodo ReadToFollowing&amp;nbsp;che accetta una stringa che fa avanzare l'XmlReader fino al punto desiderato. Se volete skippare tutti i nodi fino al nodo "fratello" di quello corrente (un altro nodo alla stessa profondità con lo stesso nome di tag) utilizzate il metodo ReadToNextSibling.
La classe XmlNodeReader&amp;nbsp;è una classe derivata da XmlReader, che ne specializza il comportamento permettendo la navigazione di un singolo nodo (XmlNode).&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/65780.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/01/10/65780.aspx</guid>
            <pubDate>Wed, 10 Jan 2007 17:01:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/01/10/65780.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/65780.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/65780.aspx</trackback:ping>
        </item>
        <item>
            <title>[70-526, #3] Altri dettagli sulla gestione dei documenti XML</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/01/10/65704.aspx</link>
            <description>Vediamo nel dettaglio altri aspetti del DOM del .NET Framework che ci permettono di lavorare sui nodi di un documento XML. La classe XmlDocument espone una serie di metodi riconoscibili&amp;nbsp;dal prefisso Create, che consentono di creare nuovi attributi (CreateAttribute), commenti (CreateComment), elementi (CreateElement), nodi (CreateNode) e quant'altro.  XmlNodeList listNodes = _doc.GetElementsByTagName(&amp;quot;book&amp;quot;);
XmlNode nodoTrovato = listNodes[0];
XmlAttribute newAttribute = _doc.CreateAttribute(&amp;quot;id&amp;quot;);
newAttribute.InnerText = &amp;quot;1&amp;quot;;
nodoTrovato.Attributes.Append(newAttribute);

Il codice qui sopra recupera tutti gli XmlNode chiamati book e prende il primo. Poi crea un nuovo attributo - notare che il costruttore di XmlAttribute prende il nome dell'attributo stesso - gli&amp;nbsp;assegna un valore importantissimo, "1" ;-), e lo aggiunge al nodo&amp;nbsp;di cui abbiamo ottenuto il riferimento&amp;nbsp;prima. Se salvassimo su file con il metodo&amp;nbsp;Save vedremmo:

&amp;lt;book id=&amp;quot;1&amp;quot;&amp;gt;
    &amp;lt;author&amp;gt;Terry Brooks&amp;lt;/author&amp;gt;
    &amp;lt;title&amp;gt;La Spada di Shannara&amp;lt;/title&amp;gt;
    &amp;lt;pages&amp;gt;450&amp;lt;/pages&amp;gt;
    &amp;lt;year&amp;gt;1998&amp;lt;/year&amp;gt;
&amp;lt;/book&amp;gt;

Possiamo clonare un XmlNode con la chiamata al metodo CloneNode. Per esempio, sempre tenendo presente le righe di codice scritte sopra, possiamo clonare l'oggetto nodoTrovato ed ottenere nodoClonato. Questo metodo accetta un parametro bool che esprime se la clonazione deve avvenire anche per tutti&amp;nbsp;gli eventuali&amp;nbsp;child nodes dell'XmlNode che stiamo clonando. Possiamo quindi indicare true o false a seconda di quello che ci serve. Il metodo ritorna un altro oggetto XmlNode che va inserito nell'XmlDocument dove ci serve. Per esempio:
// Aggiunge nodoClonato in fondo, dopo tutti i &amp;lt;book&amp;gt;
_doc.ChildNodes[0].AppendChild(nodoClonato);

// Aggiunge nodoClonato prima di tutti i &amp;lt;book&amp;gt;
_doc.FirstChild.PrependChild(nodoClonato);
AppendChild e PrependChild (di cui parlava mio fratello nel mio ultimo post) sono due metodi che inseriscono XmlNode in ultima ed in prima posizione rispetto ai child nodes dell'XmlNode su cui stiamo effettuando l'operazione.&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/65704.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/01/10/65704.aspx</guid>
            <pubDate>Wed, 10 Jan 2007 11:09:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/01/10/65704.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/65704.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/65704.aspx</trackback:ping>
        </item>
        <item>
            <title>[70-526, #2] Manage XML with XML Document Object Model</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/01/09/65609.aspx</link>
            <description>Un documento XML viene rappresentato in memoria attraverso la classe XmlDocument. Tutti gli oggetti .NET che hanno a che fare con il trattamento di documenti XML sono contenuti all'interno del namespace System.Xml. Non so il perchè, ma tutte le volte che devo caricare un documento XML sono convinto di usare il metodo Load come se fosse statico, mentre è di istanza: quando me lo ricorderò, sarà ormai troppo tardi! :-) Abbiamo due strade: una prevede l'utilizzo del metodo Load, l'altra il metodo LoadXml. Con quest'ultimo metodo possiamo caricare un documento XML direttamente da una stringa, come qui sotto: StringBuilder bld = new StringBuilder();
bld.AppendLine(&amp;quot;&amp;lt;books&amp;gt;&amp;quot;);
bld.AppendLine(&amp;quot;&amp;lt;book&amp;gt;&amp;quot;);
bld.AppendLine(&amp;quot;&amp;lt;author&amp;gt;Terry Brooks&amp;lt;/author&amp;gt;&amp;quot;);
bld.AppendLine(&amp;quot;&amp;lt;title&amp;gt;Le Pietre Magiche&amp;lt;/title&amp;gt;&amp;quot;);
bld.AppendLine(&amp;quot;&amp;lt;pages&amp;gt;450&amp;lt;/pages&amp;gt;&amp;quot;);
bld.AppendLine(&amp;quot;&amp;lt;year&amp;gt;1998&amp;lt;/year&amp;gt;&amp;quot;);
bld.AppendLine(&amp;quot;&amp;lt;/book&amp;gt;&amp;quot;);
bld.AppendLine(&amp;quot;&amp;lt;/books&amp;gt;&amp;quot;);

string xml = bld.ToString();

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
Usando uno StringBuilder costruisco un documento XML minimale, ma tecnicamente valido. Usando LoadXml, carichiamo la stringa in un XmlDocument. Se il documento XML non dovesse essere well-formed, il framework solleva l'exception XmlException. Il metodo Load invece carica l'XML da un file fisico su disco, da uno Stream, da un TextReader o da un XmlReader.
Una volte che il documento è stato caricato in memoria, il FW ci mette a disposizione tutta una serie di metodi che ci permettono di navigare il documento o di ricercare informazioni al suo interno. Il metodo GetElementsByTagName ci ritorna un'istanza di XmlNodeList che contiene l'elenco di tutti i tag XML con un certo nome, specificato nella chiamata.
XmlNodeList nodes = doc.GetElementsByTagName(&amp;quot;book&amp;quot;);
In questo caso, l'oggetto nodes contiene in questo caso un solo oggetto XmlNode. Se vogliamo fare ricerche un po' più complesse usando XPath, abbiamo due metodi: SelectNodes&amp;nbsp;(che ritorna un XmlNodeList che contiene i nodi che soddisfano i criteri di ricerca espressi in XPath) e SelectSingleNode&amp;nbsp;(che invece ritorna il primo XmlNode trovato). XmlDocument espone le proprietà FirstChild&amp;nbsp;e LastChild&amp;nbsp;che ritornano rispettivamente il primo e l'ultimo XmlNode presente nel documento caricato. La proprietà ParentNode&amp;nbsp;permette di ottenere l'istanza di XmlNode padre rispetto a quella corrente. La proprietà NextSibling&amp;nbsp;ritorna un XmlNode che è il "fratello" successivo dell'XmlNode corrente, mentre PreviousSibling&amp;nbsp;percorre l'XML in senso opposto. Se avessi tanti &amp;lt;book&amp;gt; inseriti nel blocco XML sopra, potrei saltare da uno all'altro semplicemente 1) ottenendo un riferimento XmlNode al primo &amp;lt;book&amp;gt; inserito nel documento e 2) chiamando NextSibling per balzare da uno all'altro.
Ovviamente, ci sono tutta una serie di funzionalità anche per modificare il documento, aggiungendo e rimuovendo XmlNode dove necessario. AppendChild, CreateNode, ImportNode&amp;nbsp;(per importare XmlNode da un documento all'altro), InsertAfter, InsertBefore&amp;nbsp;sono alcuni dei metodi esposti da XmlDocument. RemoveAll, RemoveChild&amp;nbsp;e ReplaceChild&amp;nbsp;sono piuttosto auto-esplicativi.
L'oggetto XmlDocument eredita da XmlNode. Effettivamente, ne condivide buona parte dell'interfaccia. Basta dare un'occhiata ai membri esposti da XmlNode per farsene un'idea. La prima cosa che salta all'occhio è che XmlNode non&amp;nbsp;espone eventi, mentre XmlDocument sì: se volessi monitorare in qualche modo tutto quello che accade ad un certo nodo XML (modifiche al suo InnerText, per esempio), quindi, non posso sottoscrivere un evento specificatamente per quel nodo, ma quelli relativi all'intero documento. Il FW2.0 ci permette di gestire&amp;nbsp;una piccolo&amp;nbsp;set di eventi relativi ai nodi XML: li potete vedere elencati qui&amp;nbsp;(cancellazione, inserimento e modifiche ai nodi del documento). Gli event handler fanno uso della classe XmlNodeChangedEventArgs&amp;nbsp;che espone una serie di membri per capire esattamente cosa è successo e dove.&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/65609.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/01/09/65609.aspx</guid>
            <pubDate>Tue, 09 Jan 2007 13:12:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/01/09/65609.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/65609.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/65609.aspx</trackback:ping>
        </item>
        <item>
            <title>[70-526, #1] Create event handlers for Windows Forms and controls</title>
            <link>http://blogs.ugidotnet.org/idamiani/archive/2007/01/08/65492.aspx</link>
            <description>In questo antico post, descrivevo come gestire e creare event handler con il framework 1.1. Con il FW2.0 nulla è cambiato: tutti gli oggetti hanno un certo numero di eventi, a ciascuno dei quali possiamo associare un handler, ovvero un metodo privato che viene eseguito quando quell'evento viene sollevato dal CLR. Per esplorare gli eventi esposti da un certo oggetto posto su una Windows Forms, è sufficiente selezionare l'oggetto a design-time, aprire la Properties Windows e cliccare sull'icona del lampo. Il tipo ed il numero di eventi dipende ovviamente dall'oggetto con cui abbiamo a che fare. Per creare un event handler, è sufficiente fare doppio-click sull'evento che ci interessa gestire. Per esempio,&amp;nbsp;possiamo&amp;nbsp;scrivere codice per&amp;nbsp;l'evento FormClosing su una WF semplicemente facendo doppio-click sulla riga nella Properties Windows. Il designer di VS2005 ci porta direttamente nell'editor di codice: private void FormEventHandler_FormClosing(object sender, FormClosingEventArgs e)
{

}
Ogni event handler è come al solito due parametri. Uno è il sender, che identifica l'oggetto che ha sollevato l'evento: è di tipo object, ovviamente. Il secondo parametro dipende dall'evento. In questo caso è di tipo FormClosingEventArgs, una classe che ci permette per esempio di annullarne la chiusura o capire chi stava chiudendo e perchè il form stava per essere chiuso.
L'esame 70-526 ci chiede due cose in particolare: use the Windows Forms designer to create event handler. Ed è quello di cui ho parlato qui sopra, ovvero saper esplorare nella Properties Windows l'evento che ci interessa e fare doppio-click. L'altra è use the Windows Forms designer to create default event handler. Questo può essere fatto molto semplicemente facendo doppio-click sull'oggetto della WF. Ogni controllo&amp;nbsp;ha un default event handler, che banalmente può essere descritto come l'evento di più frequente utilizzo (ad esempio, il Click su un Button). Quando sviluppiamo nostri controlli, possiamo utilizzare l'attributo DefaultEventAttribute proprio a questo scopo.
Un'altra questione importante: connect multiple events to a single event handler. Detto in altri termini: avere un'unica routine .NET capace di rispondere a più eventi diversi. Per far questo, è ovviamente necessario che la firma della routine sia la stessa. Questa tecnica ci permette di avere un certo numero di Button sulla WF il cui event handler sull'evento Click sia lo stesso, risparmiando così codice e codice da scrivere e da debuggare. Il parametro sender di cui ho parlato prima serve proprio per questo, ovvero a discriminare quale oggetto ha sollevato l'evento. Questo può essere ottenuto anche da IDE, perchè la Properties Windows è sensibile: non solo possiamo creare nuovi event handler, ma possiamo eventualmente selezionare dalla ComboBox la routine già esistente nel codice e che si adatta a gestire l'evento correntemente selezionato.
Come avevo già detto l'anno scorso, gli eventi vengono sottoscritti al loro event handler con una semplice linea di codice, che finisce nel FormName.Designer.cs. Nel caso dell'evento FormClosing, avremo quindi:
this.FormClosing += new FormClosingEventHandler(this.FormEventHandler_FormClosing);
Questo codice è inserito nella InitializeComponent() della WF su cui stiamo lavorando. Possiamo ovviamente ottenere lo stesso risultato senza usare il designer di VS2005: se facciamo un cut &amp;amp; paste nell'evento Load della WF otteniamo esattemente lo stesso risultato. Questo è di fondamentale importanza quando vengono creati ed aggiunti nuovi controlli a run-time sulla WF, un po' come succede con Happy Sign, dove ogni volta che si aggiunge una firma vengono associati gli event handler necessari.
Per la questione use the code editor to override methods defined in the base class è tutto molto semplice. Dall'editor di VS2005, possiamo cominciare a scrivere un nuovo metodo usando la keyword override. L'Intellisense - che tanto stupido non è - mostra un elenco di tutti quei membri (properties, indexers e events) della classe base che possiamo ridefinire. Ciò implica diverse cose: il metodo della classe base può essere ridefinito se è stato definito virtual:&amp;nbsp;per default, in C# i metodi non sono virtuali. Ciò significa che non possiamo ridefinire tutto ciò che vogliamo. Vi consiglio la lettura di questa pagina di MSDN che descrive bene tutte le implicazioni di virtual, new ed&amp;nbsp;override. Se è vero che possiamo ridefinire il comportamento di un evento, possiamo comunque chiamare il metodo della classe base attraverso l'utilizzo della keyword base.
Gli ultimi due punti per questa parte dell'esame - davvero molto semplice, devo dire - riguardano manage mouse and keyboard events within Windows Forms applications. E' possibile avere una carrellata degli eventi disponibili guardando la Properties Window nella modalità Categorized. Il gruppo Key contiene 4 eventi per la tastiera (KeyDown, KeyPress, KeyUp e PreviewKeyDown), mentre il gruppo Mouse contiene 6 eventi per il mouse (MouseDown, MouseEnter, MouseHover, MouseLeave, MouseMove e MouseUp). Non sto a mettervi il link per ogni evento, vi lascio questo che elenca tutti gli eventi esposti dalla classe Control. A seconda dell'evento che decidiamo di usare, abbiamo diverse opzioni. Le elenco in breve.
L'evento MouseDown (così come MouseMove e MouseUp) fa uso della classe MouseEventArgs, che espone tra le altre cose la proprietà Button, che ci permette di capire quale bottone del mouse è stato cliccato. La stessa filosofia la si applica con la tastiera: a seconda dell'evento, possiamo capire quale tasto è stato premuto e se insieme a lui è stato premuto qualche tasto come CTRL, ALT o SHIFT (vedere la classe KeyEventArgs per maggiori informazioni). Questo può essere fatto in due modi: usando le proprietà read-only esposte da KeyEventArgs (Alt, Control e Shift) oppure leggendo il valore della proprietà Modifiers.&lt;img src="http://blogs.ugidotnet.org/idamiani/aggbug/65492.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/idamiani/archive/2007/01/08/65492.aspx</guid>
            <pubDate>Mon, 08 Jan 2007 15:14:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/idamiani/archive/2007/01/08/65492.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/idamiani/comments/commentRss/65492.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/idamiani/services/trackbacks/65492.aspx</trackback:ping>
        </item>
    </channel>
</rss>