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è sia particolarmente complicato, quanto perchè è creato in WPF e magari qualche informazione può 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 è 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ù che comparirà dentro WLW (il file Icon.png, che è definita nella soluzione VS2005 come Embedded Resource), indicare l'url di riferimento del plug-in e per dare una descrizione (visibile dal menù Tools --> Preferences --> Plugins).
Il metodo CreateContent è piuttosto semplice. La cosa più importante è il secondo parametro newContent: esso è una stringa che viene passata come riferimento. Ciò significa, banalizzando un po', che viene ritornata all'istanza di WLW aperta. Il metodo ritorna un DialogResult: se dal metodo ritorniamo 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 è una Window), la visualizza sullo schermo come modale utilizzando il metodo ShowDialog() e controlla come è 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 coinvolge WPF coinvolge la window ChooseEmoticon, che è creata con un po' di XAML ed un po' di code-behind. La classe ChooseEmoticon deriva direttamente da Window ed aggiunge una proprietà read-only, ImageUrl, che vedete nel blocco di codice sopra. Tale proprietà, di tipo string, contiene una cosa del tipo:
<IMG src="http://www.tuttogratis.it/img/emoticons/{0}" border=0>
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 è definito come partial. E' possibile vedere la definizione delle due proprietà di cui parlavo prima: ImageUrl è la più importante, perchè 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.