<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>I miei freeware</title>
        <link>http://blogs.ugidotnet.org/IDamiani/category/I miei freeware.aspx</link>
        <description>Sviluppo dei miei software freeware, avanzamento dei lavori, proposte, discussioni e analisi</description>
        <language>it-IT</language>
        <copyright>Igor Damiani</copyright>
        <generator>Subtext Version 2.6.0.0</generator>
        <item>
            <title>Nuove features ed un nuovo installer per il mio emoticons plug-in</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/19/71116.aspx</link>
            <description>Ieri mattina, sfruttando un po' di tempo libero, ho preparato un nuovo installer per il mio famigerato plug-in per Windows Live Writer, con le funzionalità di cui parlavamo l'altra volta. In particolare sottolineo:  le emoticons vengono salvate in C:\Documents and Settings\All Users\Application Data\VivendoByte Emoticons è possibile organizzare le emoticons in più subfolders rispetto alla directory del punto (1) quando si clicca su una emoticon, oltre alla preview in basso a sinistra, appare anche l'url che verrà utilizzata per l'inserimento dell'emoticon stessa ho diminuito di un po' la dimensione dei Button per ciascuna emoticon L'installer è in formato MSI, ed è liberamente scaricabile dallo stesso URL dell'altra volta, cioè da qui. L'installer verifica che abbiate installato Windows Live Writer, altrimenti si interrompe: segnalatemi eventuali problemi. L'installer di default installa tutto dentro la directory C:\Program Files\VivendoByte\VivendoByte Emoticons plug-in, come riportato qui sotto:   E'&amp;nbsp;necessario (per adesso)&amp;nbsp;eseguire a mano Install.bat per copiare la dll dentro il path di Windows Live Writer e per copiare le emoticons nel posto giusto. Il file batch è abbastanza semplice:  xcopy VivendoByteEmoticons.dll &amp;quot;%ProgramFiles%\Windows Live Writer\Plugins&amp;quot; /Y
mkdir &amp;quot;%ALLUSERSPROFILE%\Application Data\VivendoByte Emoticons&amp;quot;
xcopy &amp;quot;VivendoByte Emoticons\*.*&amp;quot; &amp;quot;%ALLUSERSPROFILE%\Application Data\VivendoByte Emoticons&amp;quot; /Y
Utilizzo qualche variabile d'ambiente per essere sicuro di copiare le cose giuste nel posto giusto. Declino ogni responsabilità di scrittura di files in post indesiderati. Sulle altre cose sto lavorando con calma. Se oggi ho tempo faccio richiesta su CodePlex, così sarà disponibile a tutti anche il codice sorgente, che può fare comodo.
Scarica il plug-in da qui&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/71116.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/19/71116.aspx</guid>
            <pubDate>Mon, 19 Feb 2007 13:48:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/19/71116.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/71116.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/71116.aspx</trackback:ping>
        </item>
        <item>
            <title>Un FolderButton per il VivendoByteEmoticons plug-in</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/15/70867.aspx</link>
            <description>L'altra volta avevo accennato all'idea di poter organizzare le emoticons in sotto-folder, contenuti in: C:\Documents and Settings\All Users\Application Data\VivendoByte Emoticons. Notare che la directory non è più per-user. Questo implica il fatto che una volta che il plug-in viene installato, tutti gli utenti condividano lo stesso set di emoticons. Niente di male, direi. L'altra volta avevo accennato al fatto che i Button che contengono le emoticons sono contenuti all'interno di un WrapPanel. Tale WrapPanel è definito nello XAML della Window ChooseEmoticon.  &amp;lt;WrapPanel Grid.Column=&amp;quot;0&amp;quot; Grid.Row=&amp;quot;1&amp;quot;
    Name=&amp;quot;MainPanel&amp;quot; ItemHeight=&amp;quot;{StaticResource Size}&amp;quot; ItemWidth=&amp;quot;{StaticResource Size}&amp;quot;&amp;gt;
&amp;lt;/WrapPanel&amp;gt;
La classe ChooseEmoticon dispone di un metodo privato populateIcons(), che viene chiamato nel costruttore e successivamente&amp;nbsp;ogni volta che viene cambiata directory. Tale metodo fa quanto segue:

svuota i Children del WrapPanel
eventualmente aggiunge un pulsante per tornare su di una directory
aggiunge tanti FolderButton quanti sono i sotto-folder presenti nella directory corrente
aggiunge tanti Button quanti sono i files .GIF presenti nella directory corrente
aggiorna la proprietà Text del TextBlock per indicare all'utente quante emoticons ci sono
Il punto (2) richiede un breve chiarimento. Non voglio che l'utente navighi al di fuori di C:\Documents and Settings\All Users\Application Data\VivendoByte Emoticons, pertanto il FolderButton che torna su appare solo se ci troviamo in una sua sotto-directory, e non negli altri casi.
Anche il punto (3) richiede un chiarimento. La classe FolderButton infatti non esiste nel FW3.0, ma l'ho creata io attraverso un piccolo blocco di XAML. Lo XAML&amp;nbsp;ovviamente non serve solo a creare Window o Page, ma a creare qualsiasi classe. La classe FolderButton eredita da un normale Button, ma ne specializza l'aspetto: utilizza una risorsa folder.bmp, in modo tale da creare un pulsante che come contenuto ha un'immagine che fa capire che si tratta di una directory. Ecco lo XAML che ho utilizzato per definire la classe FolderButton:
&amp;lt;Button x:Class=&amp;quot;VivendoByte.Emoticons.FolderButton&amp;quot;
    xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
    xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&amp;gt;
  &amp;lt;Grid&amp;gt;
    &amp;lt;Grid.ColumnDefinitions&amp;gt;&amp;lt;ColumnDefinition&amp;gt;&amp;lt;/ColumnDefinition&amp;gt;&amp;lt;/Grid.ColumnDefinitions&amp;gt;
    &amp;lt;Grid.RowDefinitions&amp;gt;&amp;lt;RowDefinition&amp;gt;&amp;lt;/RowDefinition&amp;gt;&amp;lt;/Grid.RowDefinitions&amp;gt;
    &amp;lt;Image Grid.Column=&amp;quot;0&amp;quot; Grid.Row=&amp;quot;0&amp;quot;&amp;gt;
      &amp;lt;Image.Source&amp;gt;
        &amp;lt;BitmapImage UriSource=&amp;quot;Images/folder.bmp&amp;quot; /&amp;gt;
      &amp;lt;/Image.Source&amp;gt;
    &amp;lt;/Image&amp;gt;
    &amp;lt;TextBlock
      Name=&amp;quot;folderName&amp;quot; 
      VerticalAlignment=&amp;quot;Center&amp;quot;
      HorizontalAlignment=&amp;quot;Center&amp;quot;
      Grid.Column=&amp;quot;0&amp;quot; Grid.Row=&amp;quot;0&amp;quot;&amp;gt;..&amp;lt;/TextBlock&amp;gt;
  &amp;lt;/Grid&amp;gt;
&amp;lt;/Button&amp;gt;
Di&amp;nbsp;default la classe FolderButton crea un Button con dentro l'immagine di un folder ed il cui testo è "..". Un FolderButton contiene una Grid con una sola riga ed una sola colonna. L'unica cella contiene sia l'immagine che un oggetto TextBlock, nel cui testo finisce il nome della directory a cui si fa riferimento. Notare che l'immagine viene caricata dalla&amp;nbsp;risorsa /Images/folder.bmp: ovviamente tale file è stato inserito nella soluzione come Resource.
Nel metodo populateIcons di cui parlavo prima, posso scrivere una cosa tipo:

private FrameworkElement getFolderElement(string directoryName)
{
    FolderButton btn = new FolderButton();
    btn.ToolTip = directoryName;
    btn.Tag = directoryName;
    btn.MouseDoubleClick += new MouseButtonEventHandler(FolderDoubleClicked);

    return (btn);
}
Questo metodo ritorna un'istanza di FrameworkElement: nella fattispecie proprio un FolderButton. Ad ogni istanza associo un tooltip, imposto il tag ed assegno l'handler per l'evento MouseButtonDoubleClick: quando l'utente doppio-clicca su un FolderButton, faccio altre cosine e richiamo la populateIcons() per reimpostare il WrapPanel.
Vorrei sinceramente mettere altro codice, però il fatto di non poter avere scrollbar nei blocchi di codice causa la comparsa di post lunghi un chilometro: preferisco non farlo.&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/70867.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/15/70867.aspx</guid>
            <pubDate>Thu, 15 Feb 2007 17:46:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/15/70867.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/70867.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/70867.aspx</trackback:ping>
        </item>
        <item>
            <title>Definire StaticResource via codice ed usarle nello XAML</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/13/70628.aspx</link>
            <description>Ieri Alessio mi ha dato un'idea: da buon utente del mio plug-in, mi ha chiesto di ridurre di un po' (50-60%, dice lui) la dimensione dei Button che contengono&amp;nbsp;le emoticons. Mi è sembrata una buona idea, ma poi ho pensato che fosse una cosa piuttosto soggettiva: c'è chi vorrebbe vederle grandi come una casa, e chi invece vorrebbe vederle minuscole per farcene stare di più a parità di dimensioni. Cosa c'è di meglio quindi che lasciar decidere a voi? All'interno della soluzione faccio già uso&amp;nbsp;di un file&amp;nbsp;VivendoByteEmoticons.settings, che contiene alcuni settaggi specifici per ciascun utente. Per adesso, l'unico settings si chiama&amp;nbsp;ImageUrl ed è il tag &amp;lt;img/&amp;gt; che viene usato per inserire l'emoticon all'interno del post. Ho quindi aggiunto un altro setting, chiamato Size, di tipo double, con un valore predefinito di 50. Ok, fin qua, ci siamo: abbiamo un post dove l'utente può scrivere la larghezza (e l'altezza, trattandosi di un quadrato) dei Button che contengono gli emoticons. Come facciamo ad utilizzarlo? Andiamo con calma.Il WrapPanel è ovviamente definito nello XAML:  &amp;lt;WrapPanel Name=&amp;quot;MainPanel&amp;quot; ItemHeight=&amp;quot;70&amp;quot; ItemWidth=&amp;quot;70&amp;quot;
    Grid.Column=&amp;quot;0&amp;quot; Grid.Row=&amp;quot;1&amp;quot;&amp;gt;
&amp;lt;/WrapPanel&amp;gt;
Il WrapPanel espone tra le altre cose due proprietà interessanti: ItemWidth e ItemHeight. E' abbastanza chiaro il loro scopo: ogni volta che viene un oggetto alla sua collection Children (un Button) tale oggetto assume le dimensioni indicate da queste due proprietà. Nella prima release, tale dimensione&amp;nbsp;è - come si vede sopra -&amp;nbsp;fissa, cablata nello XAML: 70 punti. Adesso dobbiamo fare in modo di utilizzare il setting Size&amp;nbsp;di cui parlavamo prima. Dovremmo poter scrivere un qualcosa del tipo:

&amp;lt;WrapPanel Name=&amp;quot;MainPanel&amp;quot;
    ItemHeight=&amp;quot;{StaticResource Size}&amp;quot;
    ItemWidth=&amp;quot;{StaticResource Size}&amp;quot;
    Grid.Column=&amp;quot;0&amp;quot; Grid.Row=&amp;quot;1&amp;quot;&amp;gt;
&amp;lt;/WrapPanel&amp;gt;
Nello XAML, le proprietà ItemHeight e ItemWidth dello WrapPanel non sono più cablate, ma fanno riferimento alla stessa StaticResource, denominata Size. Ma dove è definita questa risorsa? Ancora una volta, non avrebbe senso definirla nello XAML, perchè in realtà il valore che ci serve deve essere reperito nel file dei settings. E allora?
La soluzione che ho adottato è creare ed aggiungere una risorsa chiamata Size via codice, nel costruttore della classe ChooseEmoticon, che è la Window che contiene lo XAML che definisce il WrapPanel qui sopra. Il costruttore è il seguente:

public ChooseEmoticon()
{
    initialize();
    InitializeComponent();
    populateIcons();
}
Notare la chiamata al metodo initialize(), definito come private. Il metodo contiene...

private void initialize()
{
    // Aggiungo la risorsa ItemSize che viene poi usata dal WrapPanel
    // per settare ItemWidth e ItemHeight con la sintassi
    // {StaticResource Size}
    this.Resources.Add(&amp;quot;Size&amp;quot;, _settings.Size);

    // altro codice di inizializzazione    
}
La classe Windows espone una proprietà Resources, di tipo ResourceDictionary, attraverso la quale possiamo gestire le risorse via C#. Il codice qui sopra aggiunge una risorsa con key = "Size", ed il cui valore viene prelevato dai settings dell'utente. Occhio che la risorsa deve essere aggiunta alla Window prima della chiamata ad InitializeComponent(). Lo XAML adesso può far uso di una StaticResource attraverso la sintassi ItemHeight="{StaticResource Size}". L'unico svantaggio di questo approccio è che la risorsa non è definita a design-time, e quindi l'editor di VS2005 ci segnala un errore nello XAML, proprio perchè mentre stiamo sviluppando la risorsa Size non esiste ancora. In realtà, si può sistemare anche questo...&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/70628.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/13/70628.aspx</guid>
            <pubDate>Tue, 13 Feb 2007 12:36:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/13/70628.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/70628.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/70628.aspx</trackback:ping>
        </item>
        <item>
            <title>Autocritica sul mio plug-in</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/12/70548.aspx</link>
            <description>Vabbè che ho criticato Lorenzo quando ho bloggato sul mio plug-in, ma una buona autocritica ogni tanto ci vuole.Ci sono alcune cose che non mi piacciono del mio plug-in per Live Writer. Vediamo cosa ne pensate.  Non mi piace (ma proprio per niente!) che le immagini delle emoticons vengano prese dal percorso C:\Program Files\Windows Live Writer\Plugins\Emoticons. Non è il posto adatto, non è user-scope, sotto Vista richiede i permessi di Administrator per poterci scrivere dentro. In conseguenza del punto (1), vorrei utilizzare un altro percorso più adatto. Qualcosa del tipo C:\Documents and Settings\&amp;lt;username&amp;gt;\Local Settings\Application Data\qualcosa. Vorrei poter creare sottofolder dentro il path del punto (2), che saranno navigabili dalla Window del plug-in. Questa&amp;nbsp;dovrebbe servire&amp;nbsp;per organizzare le emoticons per categorie (sorrisi, tristi, divertenti, etc.). I sottofolder non hanno effetto sul blocco HTML generato per inserire l'emoticon nel post in WLW. Il plug-in di Lorenzo permetteva di cambiare l'url del fornitore delle emoticon. Voglio farlo anche io, così ognuno di noi può mettersi le immagini da qualche parte (un proprio spazio web) le emoticons che vuole usare e farle puntare da lì. Hostarlo su CodePlex. Altre idee? Suggerimenti? Critiche? Proposte?&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/70548.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/12/70548.aspx</guid>
            <pubDate>Mon, 12 Feb 2007 13:34:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/12/70548.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/70548.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/70548.aspx</trackback:ping>
        </item>
        <item>
            <title>[Parte 2] Qualche info tecnica sul mio plug-in</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/10/70376.aspx</link>
            <description>Per far capir meglio le logiche del layout di WPF, che sono molto diverse rispetto al classico Windows Forms, ho preferito elaborare questa immagine:   Questo&amp;nbsp;mi sa che è&amp;nbsp;il mio post più colorato!&amp;nbsp;La window ChooseEmoticon è formata principalmente da una Grid con quattro righe, che corrispondono ai colori giallo (in alto), rosa (al centro), bianco (ehm...un po' più in basso rispetto al centro) e verde+rosso (in basso). In XAML, la dichiarazione della Window è la seguente... &amp;lt;Window x:Class=&amp;quot;VivendoByte.Emoticons.ChooseEmoticon&amp;quot;
    xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
    xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
    Title=&amp;quot;VivendoByte Emoticons&amp;quot; Width=&amp;quot;400&amp;quot; Height=&amp;quot;300&amp;quot; ResizeMode=&amp;quot;CanResizeWithGrip&amp;quot;&amp;gt;
...dove viene definito il titolo, larghezza ed altezza e la modalità di ridimensionamento. Il tag di Window si chiude in fondo allo XAML. La Grid invece appare nello XAML come segue:
    &amp;lt;Grid&amp;gt;
      &amp;lt;Grid.RowDefinitions&amp;gt;
        &amp;lt;RowDefinition Height=&amp;quot;35&amp;quot;&amp;gt;&amp;lt;/RowDefinition&amp;gt;
        &amp;lt;RowDefinition Height=&amp;quot;*&amp;quot;&amp;gt;&amp;lt;/RowDefinition&amp;gt;
        &amp;lt;RowDefinition Height=&amp;quot;25&amp;quot;&amp;gt;&amp;lt;/RowDefinition&amp;gt;
        &amp;lt;RowDefinition Height=&amp;quot;60&amp;quot;&amp;gt;&amp;lt;/RowDefinition&amp;gt;
      &amp;lt;/Grid.RowDefinitions&amp;gt;
   ...
   ...
   &amp;lt;/Grid&amp;gt;
Come si vede, la Grid ha quattro righe: alcune hanno alltezza fissa (35, 25 e 60), mentre una ha un'altezza definita come * (asterisco, star o come lo chiamate voi). Al posto dei "..." ci va un altro blocco di XAML, che definisce il contenuto della Grid (TextBlock e quant'altro).

&amp;lt;TextBlock VerticalAlignment=&amp;quot;Center&amp;quot; FontSize=&amp;quot;16&amp;quot; Margin=&amp;quot;6&amp;quot; Grid.Row=&amp;quot;0&amp;quot; Grid.Column=&amp;quot;0&amp;quot;&amp;gt;
    Clicca sull'emoticon che vuoi inserire...
&amp;lt;/TextBlock&amp;gt;
&amp;lt;TextBlock Name=&amp;quot;emoticonsAvaiable&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot; FontSize=&amp;quot;12&amp;quot; Margin=&amp;quot;6&amp;quot; Grid.Row=&amp;quot;2&amp;quot; Grid.Column=&amp;quot;0&amp;quot;&amp;gt;
    Le emoticon(s) disponibili sono xxx.
&amp;lt;/TextBlock&amp;gt;
&amp;lt;WrapPanel Name=&amp;quot;MainPanel&amp;quot; ItemHeight=&amp;quot;70&amp;quot; ItemWidth=&amp;quot;70&amp;quot; Grid.Column=&amp;quot;0&amp;quot; Grid.Row=&amp;quot;1&amp;quot;&amp;gt;
&amp;lt;/WrapPanel&amp;gt;
I primi due blocchi di XAML definiscono due TextBlock: uno per la scritta "Clicca sull'emoticon che vuoi inserire..." ed un altro per "Le emoticon(s) disponibili sono xxx.". Poi viene inserito un WrapPanel, che conterrà le emoticons: si trova nella cella (0,1) della Grid - quella ad altezza variabile. Ciò significa che quando la finestra viene ridimensionata, lo WrapPanel si ridimensiona automaticamente.&amp;nbsp;I Children&amp;nbsp;contenuti nello WrapPanel vengono automaticamente riposizionati (arrange) in base alle dimensioni correnti.
Il blocco di XAML qui sopra determina il contenuto della prima, seconda e terza riga. La quarta riga (quella verde+rosso) è formata a sua volta da un DockPanel.&amp;nbsp;Docckato a&amp;nbsp;sinistra (area verde) c'è un MediaElement, che serve per fare la preview di un'emoticon. Dockkati a destra (area rossa) invece abbiamo i due Button Annulla ed Inserisci. Il blocco di XAML per fare tutto questo è il seguente:

&amp;lt;DockPanel Grid.Column=&amp;quot;0&amp;quot; Grid.Row=&amp;quot;3&amp;quot;&amp;gt;
    &amp;lt;MediaElement DockPanel.Dock=&amp;quot;Left&amp;quot; Margin=&amp;quot;10&amp;quot; Width=&amp;quot;70&amp;quot; Name=&amp;quot;emoticonPreview&amp;quot;&amp;gt;&amp;lt;/MediaElement&amp;gt;
    &amp;lt;StackPanel DockPanel.Dock=&amp;quot;Right&amp;quot; Orientation=&amp;quot;Horizontal&amp;quot; FlowDirection=&amp;quot;RightToLeft&amp;quot;&amp;gt;
        &amp;lt;Button Margin=&amp;quot;10&amp;quot; Width=&amp;quot;70&amp;quot; IsEnabled=&amp;quot;False&amp;quot; IsCancel=&amp;quot;False&amp;quot; IsDefault=&amp;quot;True&amp;quot; Name=&amp;quot;btnInsert&amp;quot; Click=&amp;quot;InsertEmoticon&amp;quot;&amp;gt;Inserisci&amp;lt;/Button&amp;gt;
        &amp;lt;Button Margin=&amp;quot;10&amp;quot; Width=&amp;quot;70&amp;quot; IsCancel=&amp;quot;True&amp;quot; Name=&amp;quot;btnCancel&amp;quot;&amp;gt;Annulla&amp;lt;/Button&amp;gt;
    &amp;lt;/StackPanel&amp;gt;
&amp;lt;/DockPanel&amp;gt;
Giocando un po' con i margini, si ottiene una buona impaginazione degli elementi e dei controlli sulla finestra. Notare che ai Button vengono impostate alcune proprietà (IsEnabled, IsCancel, IsDefault e soprattutto il Name) ed un handler per l'evento Click (Button btnInsert), che si chiama InsertEmoticon. Il codice per questo handler è ovviamente definito nel code-behind, insieme ad un altro po' di roba di cui parleremo la prossima volta.&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/70376.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/10/70376.aspx</guid>
            <pubDate>Sat, 10 Feb 2007 18:36:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/10/70376.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/70376.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/70376.aspx</trackback:ping>
        </item>
        <item>
            <title>[Parte 1] Qualche info tecnica sul mio plug-in</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/10/70371.aspx</link>
            <description>Il mio plug-in per Live Writer ha raccolto il suo primo fan. A parte scherzi, voglio descrivervi un attimo come l'ho fatto, non perch&amp;#232; sia particolarmente complicato, quanto perch&amp;#232; &amp;#232; creato in WPF e magari qualche informazione pu&amp;#242; essere utile. Le informazioni in giro per il Web per creare un plug-in per WLW sono facilmente reperibili. Tutte ci dicono che dobbiamo ereditare dalla classe ContentSource e fare l'override del metodo CreateContent. Ed &amp;#232; quello che ho fatto:  1     [WriterPluginAttribute 
  2         ("887EC618-8FBE-49a5-A908-2339AF2EC721", 
  3         "VivendoByte Emoticons", 
  4         ImagePath = "Icon.png", 
  5         PublisherUrl = "http://blogs.ugidotnet.org/idamiani", 
  6         Description = "Interfaccia WPF per inserire le tue emoticons!")] 
  7     [InsertableContentSourceAttribute("VivendoByte Emoticons")] 
  8     public class EmoticonPlugin : ContentSource 
  9     { 
 10         public override DialogResult CreateContent(IWin32Window dialogOwner, ref string newContent) 
 11         {            DialogResult returned = DialogResult.Cancel; 
 12             ChooseEmoticon window = new ChooseEmoticon(); 
 13              
 14             bool ret = window.ShowDialog().GetValueOrDefault(); 
 15  
 16             if (ret) 
 17             { 
 18                 newContent = window.ImageUrl; 
 19                 returned = DialogResult.OK; 
 20             } 
 21  
 22             return (returned); 
 23         } 
 24     }
Non date troppo peso alla formattazione del codice: ho utilizzato questo sito per ottenere la rappresentazione HTML del codice C#. Come ci mostra l'SDK di WLW, ho utilizzato la classe WriterPluginAttribute per dare un nome al plug-in, per associare un'immagine alla voce di men&amp;#249; che comparir&amp;#224; dentro WLW (il file Icon.png, che &amp;#232; definita nella soluzione VS2005 come Embedded Resource), indicare l'url di riferimento del plug-in e per dare una descrizione (visibile dal men&amp;#249; Tools --&amp;gt;&amp;nbsp;Preferences --&amp;gt; Plugins).
Il metodo CreateContent &amp;#232; piuttosto semplice. La cosa pi&amp;#249; importante &amp;#232; il secondo parametro newContent: esso &amp;#232; una stringa che viene passata come riferimento. Ci&amp;#242; significa, banalizzando un po', che viene ritornata all'istanza di WLW aperta. Il metodo ritorna un DialogResult: se&amp;nbsp;dal metodo ritorniamo&amp;nbsp;DialogResult.Cancel, il valore di newContent viene ignorato. Se dal metodo ritorniamo DialogResult.OK, il valore di newContent viene inserito nel testo del post editato in WLW. Nota: se newContent contiene codice HTML, questo codice viene inserito nel codice HTML del post. Il codice sopra istanza un oggetto ChooseEmoticon (che &amp;#232; una Window), la visualizza sullo schermo come modale utilizzando il metodo ShowDialog() e controlla come &amp;#232; stata chiusa la finestra:

se la dialog ha ritornato true, impostiamo newContent e chiudiamo il plug-in con DialogResult.OK 
se la dialog ha ritornato false, chiudiamo il plug-in con DialogResult.Cancel ed al post non accade nulla
La parte che&amp;nbsp;coinvolge WPF coinvolge la window ChooseEmoticon, che&amp;nbsp;&amp;#232; creata con un po' di XAML ed un po' di code-behind. La classe ChooseEmoticon deriva direttamente da Window ed aggiunge una propriet&amp;#224; read-only, ImageUrl, che vedete nel blocco di codice sopra. Tale propriet&amp;#224;, di tipo string, contiene una cosa del tipo:
&amp;lt;IMG src="http://www.tuttogratis.it/img/emoticons/{0}" border=0&amp;gt;
Al posto di {0} finisce ovviamente il nome dell'immagine da inserire, con un semplice string.Format. Vi riporto un blocco di codice della classe ChooseEmoticon.  1 public partial class ChooseEmoticon : System.Windows.Window 
  2 { 
  3     public partial class ChooseEmoticon : System.Windows.Window 
  4     { 
  5         string _selectedEmoticon = string.Empty; 
  6         VivendoByteEmoticons _settings = new VivendoByteEmoticons(); 
  7  
  8         public string SelectedEmoticon 
  9         { 
 10             get { return _selectedEmoticon; } 
 11         } 
 12  
 13         public string ImageUrl 
 14         { 
 15             get 
 16             { 
 17                 if (_selectedEmoticon != string.Empty) 
 18                 { 
 19                     return (string.Format(_settings.ImageUrl, _selectedEmoticon)); 
 20                 } 
 21                 else 
 22                 { 
 23                     return(string.Empty); 
 24                 } 
 25             } 
 26         } 
 27     } 
 28 }
Il tutto &amp;#232; definito come partial. E' possibile vedere la definizione delle due propriet&amp;#224; di cui parlavo prima: ImageUrl &amp;#232; la pi&amp;#249; importante, perch&amp;#232; ritorna il tag  che ho detto prima. Ho definito anche SelectedEmoticon, che invece ritorna il nome del file ("_inferm.gif") dell'emoticon correntemente selezionata.
Nel prossimo post vedremo la definizione dello XAML della window ChooseEmoticon, come viene popolato lo WrapPanel che contiene tutti i Button, qualche handler.&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/70371.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/10/70371.aspx</guid>
            <pubDate>Sat, 10 Feb 2007 17:51:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/10/70371.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/70371.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/70371.aspx</trackback:ping>
        </item>
        <item>
            <title>Inserire emoticons da Live Writer con WPF</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/09/70274.aspx</link>
            <description>Qualche giorno fa ho dato un'occhiata al plug-in di Lorenzo per inserire le emoticon da Live Writer, ma non mi è piaciuto granchè. Non ha un'anteprima dell'emoticon, perchè la ComboBox tradizionale non mostra immagini per ogni elemento inserito. Così mi sono deciso a crearne uno mio che mi piacesse di più. Perchè non farlo in WPF? Il risultato è questo...   Le emoticons sono inserite all'interno di un WrapPanel: di conseguenza, quando ridimensionate la finestra le immagini si riposizionano automaticamente. Ogni emoticon è un semplice&amp;nbsp;Button. Sebbene le emoticons siano GIF animate, nei Button viene mostrato solo il primo frame, altrimenti è quasi psichedelico vedere decine e decine di animazioni tutte in movimento. Se volete vedere l'anteprima, cliccate su un emoticon ed essa vi apparirà in basso a sinistra. Per inserire un'emoticon, o ci fate sopra doppio-click oppure cliccare sull'emoticon e poi sul pulsante Inserisci. L'url che viene inserito punta al sito www.tuttogratis.it, che è il sito dal quale provengono le emoticon. Il plug-in è liberamente scaricabile da qui. Il file zip va decompresso dentro C:\Program Files\Windows Live Writer\Plugins. Esso contiene l'assembly VivendoByteEmoticons.dll e una directory Emoticons che contiene tutti i files GIF delle emoticons che servono per le preview. Se volete aggiungere le vostre, basta copiarle dentro questa directory. Fatemi sapere se vi piace... :-) Magari scrivo un altro post più tecnico - oddio, non che ci sia molto di tecnico, però magari qualche dritta interessante c'è...&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/70274.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/09/70274.aspx</guid>
            <pubDate>Fri, 09 Feb 2007 14:56:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2007/02/09/70274.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/70274.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/70274.aspx</trackback:ping>
        </item>
        <item>
            <title>PostSpeedometer : plugin per Windows Live Writer</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2007/01/19/67724.aspx</link>
            <description>Questa mattina ho buttato giù l'idea, ma dando un'occhiata ai vari post, non è poi così dispendioso creare un plug-in per WLW funzionale e divertente. C'è una limitazione, però, che avrete notato anche voi se usate qualche plug-in: ogni plug-in è accessibile attraverso il menù Insert di WLW. Scordatevi, per esempio, di&amp;nbsp;inserire emoticon come faceva IMHO. Questi intercettava stringhe come ":-)" e le sostituiva con la sintassi HTML che invece inseriva l'immagine. Qui le cose sono diverse, perchè bisogna sempre passare dal menù Insert. Detto questo, vediamo di buttare giù un po' di idee per il mio plug-in e di condividerle con voi. Cosa voglio ottenere dal plug-in?Ho un problema: voglio che alla fine del mio post venga riportato un piccolo blocco di testo che mi dice:  a che ora ho cominciato a scrivere il post a che ora ho finito di scrivere il post l'intervallo di tempo trascorso la velocità media in caratteri/secondo con cui ho scritto il post Quindi, l'utente apre WLW, va su Insert e poi clicca su Post Speedometer, una voce di menù nuova inserita dal mio plug-in. Il primo click su questo menù salva in una variabile il DateTime.Now, dietro previa conferma. Se dice OK, infatti, la misurazione della velocità comincia e non c'è più scampo. :-) L'utente scrive il post e, indipendentemente da quanto è lungo, alla fine deve ritornare a cliccare su Insert e poi su Post Speedometer. Il plug-in rileva nuovamente il DateTime.Now, sottrae questo valore a quello iniziale, ottenendo in questo modo un TimeSpan. Posso quindi segnalare all'utente quanto ci ha messo a scrivere il post. Houston,&amp;nbsp;abbiamo un problema!Per calcolare la velocità mi manca un dato fondamentale, ovvero il numero di caratteri scritti nel post. Mi pare che l'object model non esponga questa informazioni, ma ci guardo ancora un po', poi devo fare altro.&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/67724.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2007/01/19/67724.aspx</guid>
            <pubDate>Fri, 19 Jan 2007 15:51:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2007/01/19/67724.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/67724.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/67724.aspx</trackback:ping>
        </item>
        <item>
            <title>[HappySign] Brainstorming - idee per inizio 2007</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2006/12/29/63934.aspx</link>
            <description>Tra un bug-fixing e l'altro, i check-in di Happy Sign si fanno sentire. Gli ultimi changeset non sono stati corposi in termini di numero di files modificati, ma sono stati essenziali per eliminare alcune superficiali imperfezioni. L'attuale sorgente di Happy Sign su CodePlex è piuttosto stabile - l'aggettivo "stabile" risulta da un'analisi del mio utilizzo quotidiano di Happy Sign. ;-) Ultima feature implementata: "disponibilità di una DynamicSignature"L'ultima feature interessante apportata in Happy Sign è stata implementata dal buon&amp;nbsp;Matteo. E' stata&amp;nbsp;aggiunta una proprietà Enabled alla classe DynamicSignature, che indica la disponibilità di una firma. Cosa intendiamo&amp;nbsp;con il termine&amp;nbsp;disponibilità? E' semplice: una firma è disponibile quando il codice .NET associato è valido, è compilabile e può produrre un assembly. Quando una firma è disponibile, l'utente può utilizzarla (tramite drag'n'drop o clipboard) e&amp;nbsp;può esportarla: può fare tutto quello che vuole.Se il codice .NET non è valido, è sintatticamente scorretto, non può essere compilato, gli manca qualche reference, allora la firma non è disponibile. Una firma non disponibile appare comunque sulla UI di Happy Sign, ma viene evidenziata da un'icona di avviso. L'utente non può usarla, non può esportarla, fino a quando non sistema il codice. :-) Alcune idee per il futuroNonostante tutto quello che abbiamo fatto, le idee per l'anno prossimo sono davvero tante. Le elenco qui in breve.  Utilizzo di una cache per migliorare le prestazioniQuando si decide di utilizzare una DynamicSignature, l'engine di Happy Sign compila on-the-fly il codice .NET, genera un file HappySignScript.dll nella directory privata dell'utente. Inutile dire che c'è un leggero gap di tempo, dove con gap si intende un intervallo di tempo proporzionale alla complessità del codice da compilare. Onestamente, questo attualmente non rappresenta un grande problema, ma non mi piace questo tipo di approccio. L'obiettivo è quello di avere una cache privata, dove vengono salvati tutti gli assembly. In breve: se ho una firma chiamata "Il mio prossimo compleanno", dalla sua compilazione (scatenata la prima volta che verrà usata) risulterà un assembly chiamato IlMioProssimoCompleanno.dll. Se l'utente decide di usare&amp;nbsp;in futuro&amp;nbsp;questa firma dinamica, non verrà scatenata ogni volta una nuova compilazione, ma verrà sfruttata direttamente la dll in cache. La cache deve essere aggiornata ogni volta che si modifica il codice: su questo stiamo lavorando.  Ordinare firme e categorieNell'attuale release, le categorie possono essere riordinata a piacimento, mentre le firme no. Abbiamo intenzione di dare all'utente la possibilità di ordinare secondo diversi criteri: alfabetico, frequenza di utilizzo, data di ultima modifica (sono i primi che mi vengono in mente).  Parametri delle firmeQuesto è un bel problemino. Supponiamo di aver creato una DynamicSignature che ritorna il numero di giorni che mancano al mio compleanno. Nel codice .NET associato alla firma avremo messo una variabile DateTime impostata sul nostro giorno di nascita. La firma va che è una meraviglia, decido di esportarla e di distribuirla. Arriva l'utente Piero, si importa la firma, la utilizza ma i conti non tornano, perchè nel codice è cablata la data di nascita dell'autore. L'utente Piero dovrebbe andare nel codice e correggere la data mettendo la sua. Brutto, non vi pare? Su questo siamo in alto mare - accettiamo idee &amp;amp; suggerimenti. :-) Varie ed eventualiChissà quante cose adesso non mi vengono in mente. Lunga vita ad Happy Sign! :-) [Mancano 61 giorni al mio compleanno. Ricordatevelo!]Powered by Happy Sign - http://www.codeplex.com/HappySign&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/63934.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2006/12/29/63934.aspx</guid>
            <pubDate>Fri, 29 Dec 2006 17:42:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2006/12/29/63934.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/63934.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/63934.aspx</trackback:ping>
        </item>
        <item>
            <title>[HappySign] Secondo webcast, stavolta per sviluppatori</title>
            <link>http://blogs.ugidotnet.org/IDamiani/archive/2006/12/04/58412.aspx</link>
            <description>Scaricatelo qua : link diretto al webcast&amp;nbsp;(durata circa 30 minuti, 22Mb in formato WMV) Sabato pomeriggio, sul tardi, ho trovato il tempo per parlare da solo davanti al PC per circa 30 minuti, realizzando il mio secondo webcast dedicato ad Happy Sign. I temi espressi questa volta erano rivolti agli sviluppatori: ho preparato persino delle slides (che pubblico domani), manco fosse un webcast "serio". :-))&amp;nbsp;Chi ha seguito il mio blog nei giorni scorsi, sentirà parlare di cose già trattate: SignatureBase, NormalSignature e DynamicSignature, che sono i mattoncini fondamentali su cui si appoggia l'attuale versione di Happy Sign. Ma con la mia voce, è tutta un'altra cosa! Bisogna vedere se è in meglio o in peggio. ;-) C'è una bella e semplice spiegazione sull'interfaccia IHappySignScript, che è l'interfaccia che tutte le firme dinamiche devono implementare, che prevede la creazione di un metodo GetValueParameter. Maggiori dettagli qua ve li risparmio, guardate il mio webcast. Ho aggiunto qualcosa su come unirsi al team su CodePlex (registrazione, Team Explorer, etc.) e&amp;nbsp;qualcosa sulle prossime modifiche. Personalmente, valuto positivamente questo mio secondo esperimento: la prima volta ero quasi imbarazzato davanti al mio PC (sebbene fossi da solo per avere più tranquillità), mi ero preparato una scaletta piuttosto rigida da seguire, avevo una voce più "emozionata", quasi. Sabato invece sono andato più liscio: senza scaletta, quasi improvvisando, ed in certi punti si sente anche, perchè perdo un po' il filo del discorso. Il bello della diretta! :-) Sono contento di essere riuscito a farlo, perchè questa settimana starò lontano dal PC e sparirò dalla circolazione fino a lunedì prossimo. Ho fatto vedere il video in anteprima a qualcuno del team, che l'hanno giudicato positivamente, ma giustamente con qualche critica ed osservazione. Ne aprofitto per correggere qualche imprecisione apparsa nel webcast. Le firme dinamiche devono essere per forza nella categoria "Dinamiche C#" ?Durante il webcast, creo diverse firme dinamiche come demo, inserendole tutte all'interno della categoria "Dinamiche C#". Questa cosa non è assolutamente obbligatoria: potete creare categorie nella più completà libertà, con il nome che volete, e potete inserire al loro interno ogni tipo di firma. Quello che faccio durante il webcast è puramente casuale! Ehm...Igor, il menù dalla tray-bar da dove salta fuori?Rispetto all'ultimo webcast, Happy Sign ha subìto diversi miglioramenti della UI. Tra queste, anche la comparsa di un&amp;nbsp;menù contestuale (classe ContextMenuStrip) raggiungibile dalla tray-bar. Ne ho parlato in questo post, ma magari qualcuno si chiede da dove salti fuori. Questo menù permette agli utenti di poter utilizzare le firme senza avere Happy Sign sullo schermo, ma semplicemente ridotto ad icona. Le modalità per utilizzare le firme sono attualmente tre: 1) il più figo: il drag'n'drop 2)&amp;nbsp;cliccando col destro sulla firma attraverso clipboard&amp;nbsp;e 3) il menù dalla tray-bar. Se lo vedete/ascoltate, mi dite cosa ne pensate? Scaricatelo qua : link diretto al webcast&amp;nbsp;(durata circa 30 minuti, 22Mb in formato WMV)&lt;img src="http://blogs.ugidotnet.org/IDamiani/aggbug/58412.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Igor Damiani</dc:creator>
            <guid>http://blogs.ugidotnet.org/IDamiani/archive/2006/12/04/58412.aspx</guid>
            <pubDate>Mon, 04 Dec 2006 13:00:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/IDamiani/archive/2006/12/04/58412.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/IDamiani/comments/commentRss/58412.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/IDamiani/services/trackbacks/58412.aspx</trackback:ping>
        </item>
    </channel>
</rss>