Technology Experience

.NET World

Programmazione, libri, snippet di codice, articoli tecnici

.NET World

Perchè dovreste usare il mio plug-in per inserire i tag Technorati?

Ho appena uploadato sul mio sito Sharepoint il nuovo plug-in per Windows Live Writer per taggare i propri post con i tag Technorati. Ce ne sono già in giro, ma il mio è il migliore di tutti (sempre il solito arrogante!).

Ecco i perchè:

  1. potete inserire uno o più tag in una casella di testo, separandoli con un punto e virgola ‘;’ (fin qua nulla di nuovo)
  2. i tag che avete inserito finiscono in una cache, o history che dir si voglia, serializzata in XML qua:
    C:Documents and Settings<username>Dati applicazioniVivendoByte Technorati Tags
  3. potete inserire uno o più tags non solo nella casella di testo, ma prendendoli dalla history proposta attraverso un elenco che appare a sinistra della finestra
  4. in alto a destra c’è il logo VivendoByte che potete cliccare per aprire il mio blog! E questo non è da poco, no???? 🙂

Il punto (3) permette di non star lì tutte le volte a digitare daccapo i tags, con tutti i problemi annessi e connessi. Errori di battitura, per esempio, a causa dei quali potete avere due tag come “wpf” e “WPF“, oppure “Windows Live Writer” e “WindowsLiveWriter“, oppure “ie” e “ie7“: tutte questioni che affollano un po’ troppo la nostra Tag Cloud. Inoltre, potrebbero finirci tag scritti in malomodo e sgrammaticati.

Nello screenshot qui sopra, i tag wpf e software li ho presi dall’elenco a sinistra (infatti appaiono selezionati), mentre gli ultimi due (deploy e programming) li ho digitati a mano. Se clicco Ok e confermo questi tags, questi ultimi due finiranno anche loro nella history e dalla volta successiva mi appariranno nella history per velocizzarne l’inserimento.

In più ho aggiunto due pulsanti per ripulire la history e per aprire il folder nel quale la history è salvata. Semplice ed efficace.

Il plug-in per Windows Live Writer è scaricabile da qua. Lo zip contiene l’assembly VivendoByteTechnorati.dll che va copiato in C:ProgrammiWindows Live WriterPlugins. Se trovate qualsiasi bug, per favore segnalatemelo, perchè questo plug-in mi piace e lo voglio perfetto! E per rispondere a Simone…no, l’autocomplete del tagging plugin nativo di WLW non mi piace! 🙂

Technorati Tags:  

Send to Kindle
.NET World

Automatizzare Reporting Services con codice managed

Reporting Services di SQL Server 2005 non significa solo report esposti da IIS e quindi raggiungibili via browser, ma significa anche avere un componente lato client per fare esattamente la stessa cosa. E’ quello che ho fatto nell’applicazione di fatturazione che ho reso pubblica molto, molto tempo fa.

I report sono in formato RDLC ed usando la finestra di preview è possibile stampare sulla stampante di default, esportare in PDF e fare le solite cose fattibili con un’anteprima di stampa (zoom, regolare l’orientamento della pagine, decidere la stampante, settare il numero di copie, etc.). Ma non solo.

L’architettura di Reporting Services permette di scrivere codice managed per ottenere lo stesso risultato raggiungibile dalla classica UI. Per esempio: possiamo lanciare una stampa di una certa fattura senza alcuna richiesta da parte dell’utente, e possiamo esportare un report di stampa in qualsiasi formato, tra cui il PDF. Ecco qualche link utile per questo tipo di approccio.

Programattically render pdf from ReportViewer
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=240094&SiteId=1

Walkthrough: Printing a Local Report without Preview
http://msdn2.microsoft.com/en-us/library/ms252091(VS.80).aspx

Due piccole note. L’esportazione in formato PDF è piuttosto semplice, perchè il metodo Render esposto dalla classe LocalReport non fa altro che ritornare un byte[] che poi va salvato su disco dandogli un nome come C:MioReport.pdf.
La stampa diretta su stampante è invece un po’ più impegnativa, perchè comunque passa attraverso l’uso dei tradizionali oggetti PrintDocument di .NET per stampare il documento.

Se stasera riesco, integro queste due piccole scoperte nel mio RapportinoMaker e se ce la faccio entro fine mese ho tutto automizzato. Spettacolare!

Technorati Tags:

Send to Kindle
.NET World

Uploadare un documento ad una Document Library di Sharepoint

Il sito http://enjoy.vivendobyte.net/igordamiani.it.reborn è un sito Sharepoint 2007.

All’interno di questo sito ho creato alcune liste, alcune pubbliche ed altre private. Tra queste ultime, ve ne è una in cui raccolgo rapportini e fatture che ovviamente devono rimanere privati. Ho voluto dare una marcia in più al mio RapportinoMaker, il software di cui ho parlato qua, per automizzare l’upload di documenti PDF (fatture) e documenti Excel (rapportini) su questa famigerata lista Sharepoint. Pensavo di dover lavorare con http e con NetworkCredentials, ma ho preso una strada diversa che voglio illustrare perchè può essere utile anche a voi.

Come giustamente mi ha fatto notare mio fratello, qualsiasi lista di Sharepoint è raggiungibile anche attraverso il classico Esplora Risorse. Ciò significa che, per esempio, posso raggiungere la mia Document Library andando al path di rete:

\enjoy.vivendobyte.netigordamiani.it.reborn<nome_lista><nome_folder>

Se ci siamo già autenticati, allora il folder si apre automaticamente, altrimenti appare la classica dialog che chiede username e password. Detto questo è facile dedurre che possiamo copiare un qualsiasi file usando la classica File.Copy(source, destination): nulla di strano.

Il vero problema è che quando non ci siamo autenticati, la chiamata a File.Copy solleva un’eccezione. E’ un problema che non ho risolto, ma ci ho girato attorno. Usando questa libreria, mappo il disco di rete su un drive locale (per esempio, Z:). La procedura di mapping del disco passa da un’autenticazione (username + password), quindi il problema è risolto.

Riassumendo, per l’upload di un file su una Document Library di Sharepoint 2007 faccio quanto segue:

  1. connetto il path remoto \enjoy.vivendobyte.netigordamiani.it.reborn sul drive locale Z:
  2. copia il file dal mio PC locale a Z:<nome_lista><nome_folder><nome_file>
  3. cancello il drive mappato Z:

Ecco un piccolo stralcio di codice per darvi qualche spunto:

static void Main(string[] args) { NetworkDrive nd = new NetworkDrive(); nd.LocalDrive = "Z:"; nd.Force = true; nd.PromptForCredentials = false; nd.SaveCredentials = true; nd.ShareName = @"\nome_dominio ome_sito_wss"; nd.MapDrive(USERNAME, PASSWORD); string remoteFile = @"Z: ome_lista ome_cartellapippo.txt"; File.Copy(@"D:Documentipippo.txt", remoteFile, true); nd.UnMapDrive(); }

Ho nascosto le informazioni sensibili. Le costanti USERNAME e PASSWORD contengono lo username e la password necessarie per loggarsi sul sito Sharepoint. Con la chiamata a MapDrive() connetto il network path, poi copio il file, poi sconnetto tutto.

Technorati Tags:

Send to Kindle
.NET World

RapportinoMaker: WOW!

Sul mio blog di UGIdotNET avevo parlato una volta di come sfrutto una serie di tecnologie per mettere in piedi un sistema per permettermi di fare i rapportini di lavoro e le relative fatture con un software estremamente automizzato, che mi consente davvero di risparmiare un bel po’ di tempo e di avere meno grattacapi alla fine di ogni mese. Siccome non ho trovato il link, rispiego tutto daccapo.

Alla fine di ogni mese, devo preparare un rapportino di lavoro in Excel con l’elenco di tutte le giornate lavorative che ho fatto. L’elenco deve essere fatto giorno per giorno, bisogna indicare quante ore sono state fatte e così via. Invece di compilare a mano, utilizzo un sistema molto più semplice: sul mio palmare utilizzo Agenda Fusion. Con questo software segno quotidianamente la giornata lavorativa, intesa come luogo di lavoro, ora di arrivo, ora di uscita ed altre informazioni adesso non pertinenti. Quando arrivo a casa sincronizzo il contenuto dell’agenda con Microsoft Outlook 2007. Va da sè, quindi, che posso calcolare quanti giorni ho lavorato in un mese semplicemente contando le giornate dentro Outlook.

Ed è quello che ho fatto con RapportinoMaker, un software di mia creazione e che non distribusco nè vendo.
Ecco alcune caratteristiche:

  1. compilazione automatica del foglio Excel, con relativo salvataggio in una directory apposita e con un nome del file “sensato” (ad esempio: Rapportino_Maggio_2007.xls)
  2. grazie a domain-model, DAL, NHibernate e Reporting Services, posso generare automaticamente la fattura con il software di fatturazione che mi sono sviluppato. Sì, esatto, è lo stesso che feci ai tempi e che fece vedere Davide Mauri ad una sessione degli scorsi Community Days a Milano. Il domain-model espone oggetti come Articolo, Cliente, Fattura e RigaFattura, che possono essere ovviamente istanziati e creati programmaticamente. La fattura viene creata impostando cliente e data ed una sola riga di fattura che contiene l’articolo. Quest’ultimo è una semplice attività di consulenza, dove il costo unitario è la mia tariffa giornaliera e la quantità è il numero di giornate lavorative conteggiate. Poi salvo il tutto su database. Nei prossimi giorni vorrei generare automaticamente il file PDF e le copie fisiche sulla stampante di default
  3. dentro Microsoft Outlook 2007, mi salvo nelle Bozze un’e-mail precompilata con destinatario, oggetto, testo ed allegato per spedire la fattura ed il rapportino alle persone competenti
  4. vorrei uploadare sia il rapportino Excel sia la fattura in formato PDF su una lista Sharepoint privata. Così, ovunque io mi trovi, posso accedere a tutte le informazioni e se qualcuno mi chiama e mi dice: “Igor, dovresti mandarmi il rapportino di 2 mesi fa” io non vado in panico e so esattamente dove andare

Tutto questo, ve lo posso assicurare, è molto più semplice di quello che può sembrare. Adesso che ho sviluppato tutto il sistema, faccio davvero molto poco. Arrivo a casa e, quando mi ricordo, sincronizzo il palmare. Alla fine di ogni mese, lancio una console application che fa tutto quello descritto qui sopra, facendomi davvero guadagnare un bel po’ di tempo. Spettacolare, sono davvero soddisfatto.

Vi chiederete perchè ne parlo proprio stasera.

Ad Aprile ho cambiato la società per la quale faccio consulenza, e questa sera mi sono messo qui a modificare il mio software per adeguarlo alle nuove esigenze: prima fra tutti, il template del foglio Excel per il rapportino è diverso, e quindi ho dovuto modificare la logica per la compilazione automatica. Nulla di che: celle in posizione diverse e roba del genere. In più ho sistemato qualche bug che giaceva nel codice da un po’ troppo tempo. Usando TFS per questo progetto, mi sono ritrovato una serie di WorkItem che mi aspettavano.

Per oggi chiudo qua. Con il giusto mix di sport e programmazione, oggi è stata davvero una domenica con i fiocchi!

Technorati Tags:

Send to Kindle
.NET World

In WPF i controlli non devono avere per forza un nome

Il titolo del post è talmente significativo che potrei addirittura non scrivere nulla qua.

Questa cosa dei controlli senza nome è una cosa a mio avviso comodissima, perchè non è detto che tutti i controlli che mettiamo su una Window o una Page abbiano davvero un significato dal punto di vista programmatico. Pensiamo alle classiche Windows Forms: credo che sia successo a tutti di mettere delle Label solo per dare un’etichetta a TextBox o ad altri controlli di input. Il designer ci mettere per default un nome come Label1, e poi dobbiamo essere noi a dare un nome più sensato. In certi casi, come questo che ho appena citato, il nome non lo vorrei proprio dare, perchè non mi interessa vedere quella label nel codice C#. O comunque, possiamo darlo magari in un secondo momento, quando ci rendiamo conto che magari ci serve gestirlo in qualche modo.

In WPF accade esattamente così. Quando aggiungiamo un nuovo controllo su una Window esso non ha alcun nome. Lo capiamo perchè nello XAML il tag – ad esempio <TextBox />, non ha l’attributo Name. In questo caso, quel controllo non ha nome e non possiamo gestirlo nel code-behind C# attraverso una variabile dedicata. Trovo comodissimo poter aggiungere controlli no-named, solo per creare la UI e per abbellirla, senza che questo mi vada ad intaccare e a “sporcare” il codice, l’Intellisense e così via. Possiamo ovviamente recuperarne l’istanza in altri modi, come navigare nel visual tree della Windows e cercare un determinato oggetto, perchè l’oggetto esiste a tutti gli effetti, solo che non ha nome e quindi il compilatore evita di istanziare una variabile nel code-behind.

Technorati Tags:

Send to Kindle
.NET World

Disponibile per il download: Flickr Browser

Ho messo on-line il progetto Flickr Browser di cui ho parlato qualche tempo fa sul mio blog. Le caratteristiche che mi sento di evidenziare in questo mio piccolissimo progetto sono le seguenti:

  • possibilità di avere l’elenco dei set fotografici di un determinato utente
  • possibilità di sfogliare tutte le foto appartenenti ad un certo set fotografico
  • avere le informazioni EXIF di una certa foto
  • possibilità di salvare su disco locale una certa foto

In una versione futura, sulla quale sto lavorando, vorrebbe andare anche a scrivere su Flickr, nel senso di poter uploadare qualche foto in un qualche set fotografico già esistente. Già adesso sulla UI è presente una TextBox per ciascun set sulla quale diventerà possibile droppare un file JPG dal PC locale per uploadarlo sul portale. Per farlo, però, bisogna autenticarsi verso Flickr con permessi di scrittura: la cosa non è così difficile, anzi, solo che non ho ancora implementato l’interfaccia per farlo.

Il progetto è ovviamente stato realizzato in WPF ed è downloadabile da qua. Ricordo che il download comprende i sorgenti del progettino, e quindi potete un po’ dare un’occhiata a come ho usato data-binding (davvero tanto), templates, ListBox, eventi e quant’altro. Credo sia il primo progetto WPF per accedere a Flickr, tra l’altro, dal momento che googlando non ho trovato nulla di questo tipo. Vorrei migliorare e potenziare un po’ il software, per esempio aggiungendo ricerche per tags, per data e così via. Ma trattandosi di un progetto freeware, non c’è alcuna fretta.

Technorati Tags:

Send to Kindle
.NET World

Diversi stili nello scrivere e testare il codice

Negli ultimi 3 giorni ho incontrato 3 approcci diversi su come scrivere il codice C# e su come testarlo mentre l’applicazione è sotto sviluppo. Io sono uno di quelli che scrivono buona parte del codice a design-time, mentre non è in esecuzione e quando credono di aver implementato una certa feature mettono un breakpoint su una riga, eseguono l’applicazione e seguono il flusso del codice per vedere come va. Questo ovviamente quando mi ritrovo a scrivere codice che so essere insidioso, o del quale magari non sono del tutto sicuro. La cosa davvero comoda è che gli strumenti di programmazione di oggi, gli IDE insomma, ci danno enormi possibilità: quando siamo fermi ad un breakpoint, possiamo ritornare indietro a step precedenti, possiamo ispezionare variabili ed oggetti di ogni tipo, possiamo modificarne il valore e via dicendo. Credo di passare molto del tempo (sparo: 20-25% del tempo) a scrivere codice mentre il codice stesso è in esecuzione: mi capitava più spesso anni fa, quando lavoravo con Visual Basic 6.0, ma anche oggi bene o male faccio così. La possibilità di lavorare con il codice in esecuzione dipende dagli strumenti che si utilizzano: con il .NET Framework e Visual Studio è uno scherzo, come credo in altri ambienti, ma da quando lavoro con il .NET Compact Framework ho notato una limitazione. Se l’esecuzione del codice di ferma ad un breakpoint e poi mi metto a modificare il sorgente – magari per correggere o sistemare qualcosa – il CLR dice chiaramente che le modifiche saranno rese attive solo aver riavviato l’esecuzione del progetto stesso. Nei primi giorni di lavoro perdevo un sacco di tempo, ma già da un po’ ho imparato a giocherellare con watches per evitare tutto questo.

Una cosa che davvero non sopporto è invece fare scrivere codice, rileggerlo per vedere se è stata scritta qualche cavolata e poi lanciare l’esecuzione senza alcun breakpoint. Se il risultato è quello atteso, allora ok, altrimenti si passa a controllare il codice con breakpoint e compagnia bella. Questo imho è un gravissimo errore, perchè anche se il nostro programma ci restituisce 5 se gli diamo come input 2+3, non è detto che il flusso del codice fa davvero quello che si aspetta. Mi è capitata una volta una situazione: avere un array con n-mila elementi e doverne cercare uno in particolare. Banalmente, avevo fatto un ciclo for…next per esaminare uno ad uno tutti gli elementi e quando trovavo quello che volevo settavo una variabile di ritorno. Il problema è che non avevo messo un break nel caso di ricerca conclusa con successo: il programma ricercava correttamente l’elemento, ma perdeva un sacco di tempo a scansionare l’array anche quando ormai non serviva più. Se avessi controllato almeno una volta l’esecuzione step-by-step, probabilmente me ne sarei accorto.

Technorati Tags:

Send to Kindle
.NET World

La mia prossima lettura: The Security Development Lifecycle

Dopo un libro su WPF, finito qualche settimana fa, ecco un libro diverso, dove non si tratta di una particolare tecnologia, ma parla di security sotto diversi punti di vista: sviluppo, architettura, marketing, come vendere la sicurezza nei propri prodotti e così via. Sono ancora agli inizi, per adesso non so dirvi molto. Ho comprato il libro durante il workshop di TechNet, la settimana scorsa, al banchetto di orilla.it dopo la sessione di Francesca Di Massimo che mi ha colpito molto.

Adesso, però, ho fame.

Technorati Tags:

Send to Kindle
.NET World

[6] Il ritorno dello HockeyPlayer (data-binding con WPF)

Diamo una breve occhiata all’ultimo XAML che abbiamo scritto per ottenere una ListBox con associato un template, definito in uno UserControl separato.

<ListBox Name="lstPlayers" ItemsSource="{Binding Source={StaticResource players}, Path=HockeyPlayer}"> <ListBox.ItemTemplate> <DataTemplate> <a:HockeyPlayerTemplate /> </DataTemplate> </ListBox.ItemTemplate> </ListBox>

A questa ListBox è stato associato, quindi, un solo template, HockeyPlayerTemplate, che fa in modo che a run-time la ListBox appaia in un certo modo. Fare riferimento all’ultimo post per maggiori dettagli.

La cosa interessante è che non è detto che il template debba per forza essere deciso in fase di compilazione, ma anche durante l’esecuzione del programma stesso. Ancora più interessante: non è detto che tutti gli Items della ListBox debbano per forza utilizzare e/o avere lo stesso template. Guardate la dichiarazione di questa ListBox:

<ListBox Name="lstPlayers" ItemsSource="{Binding Source={StaticResource players}, Path=HockeyPlayer}" ItemTemplateSelector="{StaticResource selector}" />

E’ stata valorizzata la proprietà ItemTemplateSelector. Non fatevi ingannare dal nome: prima che la studiassi, pensavo che fosse una proprietà che serviva a definire un template da utilizzare come selettore, al posto del classico rettangolone blu che appare quando selezioniamo un oggetto sulla ListBox. Nulla di tutto questo. La proprietà ItemTemplateSelector specifica una classe particolare, che viene utilizzata dall’engine di WPF per determinare il template da utilizzare per ciascun item della ListBox stessa. Mi spiego meglio: in questo caso ItemTemplateSelector fa riferimento ad una risorsa statica con Key=”selector”. Tale risorsa è ovviamente definita all’interno dello stesso file XAML, e precisamente:

<Window.Resources> <a:HockeyPlayers x:Key="players" /> <a:HockeyPlayerDataTemplateSelector x:Key="selector"/> </Window.Resources>

La classe HockeyPlayerDataTemplateSelector è una classe definita nel namespace MyItemTemplate, che eredita da DataTemplateSelector. Tutto quello che dobbiamo fare, quindi, è implementare la classe, facendo l’override del metodo SelectTemplate e ritornando un’istanza di DataTemplate, che verrà utilizzata per disegnare l’item corrente. Ricordo infatti che durante l’esecuzione del codice si entra nel metodo SelectTemplate una volta per ciascun item che deve essere aggiunto alla ListBox. La mia implementazione, giusto per farvi vedere è la seguente:

public override DataTemplate SelectTemplate(object item, DependencyObject container) { if (item != null && item is HockeyPlayer) { DataTemplate ret = null; HockeyPlayer p = item as HockeyPlayer; Window window = Application.Current.MainWindow; switch (p.Sex) { case SexEnum.M: { ret = window.FindResource("templateM") as DataTemplate; break; } case SexEnum.F: { ret = window.FindResource("templateF") as DataTemplate; break; } } return(ret); } return null; }

La morale è: la classe HockeyPlayer espone una proprietà Sex, che è di tipo SexEnum, che può valere M o F. La classe HockeyPlayerDataTemplateSelector si occupa di ritornare un template piuttosto che un altro. La scelta può avvenire in base al codice che andiamo a scrivere nel metodo. Nel mio caso, ho buttato giù un semplice switch che in un caso ritorna il template denominato templateM; nell’altro ritorna templateF. I due template si differenziano l’uno dall’altro solo per il colore di sfondo: azzurro in un caso e rosa nell’altro. Un approccio di questo tipo è sprecato, perchè si potrebbe ottenere lo stesso risultato usando i triggers nativamente disponibili con WPF. Il fatto di avere una classe che si occupa di selezionare un template apre le porte ad indubbi vantaggi: estrarre la logica al di fuori della Window e, soprattutto, avere una logica mooolto più complessa rispetto a quella esprimibile attraverso i trigger. Per esempio: i trigger scattano solo quando una determinata proprietà assume un determinato valore. Ma cosa succede, per esempio, se volessimo usare un template nel caso in cui il peso sia < 90 Kg? Oppure, ancora, se un certo giocatore è alto più di 175cm? Inoltre, con i trigger possiamo cambiare valore alle proprietà, mentre con il metodo descritto in questo post possiamo anche prelevare ovviamente template molto diversi fra loro, a seconda delle necessità. Il metodo SelectTemplate può contenere tutto il codice che vogliamo, e quindi essere complesso a piacimento. Ricordiamoci solo che l’esecuzione del metodo avviene per ogni item, quindi tenere d’occhio le performance. Ad esempio, fare un window.FindResource ad ogni iterazione può essere controproducente: molto meglio cacheare da qualche parte i due template e nel metodo semplicemente ritornarli all’engine di WPF.

Tirando le somme, voglio ricordare che i due template sono stati definiti fra le risorse globali dell’applicazione. Vi riporto la definizione di uno solo dei due template, ovvero quello identificato dalla key templateM. E’ un po’ lungo, ma è lo stesso che abbiamo usato nei post precedenti:

<DataTemplate x:Key="templateM"> <DataTemplate.Resources> <a:SliderValueConverter x:Key="conv"/> </DataTemplate.Resources> <StackPanel Margin="4" Orientation="Horizontal"> <StackPanel.Background> <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5"> <GradientStop Color="Blue" Offset="0.0" /> <GradientStop Color="White" Offset="0.80" /> <GradientStop Color="Blue" Offset="1.0" /> </LinearGradientBrush> </StackPanel.Background> <TextBox Margin="4" Width="120" Foreground="Red"> <TextBox.Text> <Binding Path="Name" UpdateSourceTrigger="LostFocus"> <Binding.ValidationRules> <a:NameHockeyPlayerRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBox Margin="4" Text="{Binding Path=Weight}" Background="LightCoral" Width="30" /> <TextBlock Margin="4" Text="{Binding ElementName=sldHeight, Path=Value, Converter={StaticResource conv}}" Width="60" /> <Slider Name="sldHeight" Minimum="50" Maximum="200" Width="120"> <Slider.Value> <Binding Path="Height" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <a:HeightHockeyPlayerRule /> </Binding.ValidationRules> </Binding> </Slider.Value> </Slider> </StackPanel> </DataTemplate>

La differenza fra i due sta nel Background dello StackPanel: sono tutti e due gradienti, solo che in quello più sopra si usa il blue, nell’altro il rosa.

Technorati Tags:

Send to Kindle
.NET World

L’interfaccia di WPF è XAML, cioè XML…quindi serializzabile

Piccola riflessione della serata. L’interfaccia utente di un’applicazione WPF viene descritta da un file XML, nella fattispecie XAML. Cioè significa che è serializzabile. Ciò significa che, per esempio, possiamo in un qualsiasi momento fare una sorta di dump di una Windows – supponiamo – e salvare il tutto in un file XML su disco. Il dump contiene lo stato di tutta la Window: dalla Windows stessa a tutti i controlli che vi sono contenuti, con tutte le loro proprietà. Sarebbe interessante, per esempio, avere una Window ed intercettare eventuali eccezioni nate al suo interno. Quando viene scatenata un’eccezione, si fa il dump dell’interfaccia (ovvero il visual tree dell’intera Window), lo si salva su disco, così magari possiamo dare un’occhiata a quali valori c’erano sui controlli prima che il tutto generasse l’eccezione.

Dal momento che l’engine di WPF può caricare un blocco XAML a runtime, così evidentemente deve essere possibile anche l’operazione inversa, cioè ottenere lo XAML da un’interfaccia che sta vivendo in questo momento sullo schermo in una Windows o in una Page.

Nessun contenuto tecnico, solo una riflessione su cui vorrei ragionare e fare qualche test nei giorni seguenti.
Chiedere alla classe VisualTreeHelper per maggiori informazioni al riguardo. Se avete installato la MSDN Library in locale, date un’occhiata al codice che c’è di esempio per questa classe, perchè può dare l’idea.

Technorati Tags:

Send to Kindle