Prima di ogni altra cosa, lo XAML viene utilizzato per definire Window o Page. All'interno di ciascuna Window o di ciascuna Page il più delle volte inseriamo un Panel - in una delle sue possibili forme - e via via tutti i relativi UIElement, figli del Panel, che comporanno l'aspetto della finestra o della pagina. Nulla di strano, in questo.
Lo XAML può essere utilizzato anche per definire classi custom, derivandole da una classe UIElement già esistente, come per esempio Button. Quando in passato nei miei post ho parlato delle classi FolderButton o EmoticonButton non ho fatto altro che fare proprio quello di cui sto parlando. Attraverso lo XAML ho creato un custom control, che ovviamente non eredita da Window o Page, bensì da una classe base da cui vogliamo partire per estenderne le funzionalità. Nel caso di FolderButton o di EmoticonButton, come è facile intuire, sono partito da Button. Come?
Da Visual Studio 2005 clicchiamo con il pulsante destro sul progetto, e clicchiamo su Add new Item. Tra tutti i tipi di files che possiamo aggiungere al progetto, selezioniamo User Control (WPF) e modifichiamone il nome con qualcosa di sensato. Il nome predefinito del file è UserControl1.xaml: direi che è un po' vago, perciò cambiamolo a mano in SampleButton.xaml. Come ogni XAML che si rispetti, anche questo possiede ovviamente un code-behind in C#. Apriamo il file SampleButton.cs, che conterrà una cosa tipo:
public partial class SampleButton : System.Windows.Controls.UserControl
{
public SampleButton()
{
InitializeComponent();
}
}
Di default, ogni custom control deriva da UserControl, perchè ci si aspetta che vogliate creare un controllo composto da altri controlli base (del tipo...due TextBox per editare qualcosa, ed un Button per confermare). Questo non è il nostro caso, perchè noi vogliamo creare un controllo che erediti da Button. Non ci resta quindi che modificare il codice ed indicare l'ereditarietà come la vogliamo noi:
public partial class SampleButton : System.Windows.Controls.Button
Se proviamo a compilare, avremo il messaggio di errore Partial declarations of '<class_name>' must not specify different base classes. in realtà, dobbiamo ritoccare anche lo XAML, perchè anche in questo file è indicata la classe base dalla quale stiamo ereditando. Solo che in questo momento abbiamo un conflitto di interessi: il codice C# dice di ereditare da Button, mentre lo XAML dice di ereditare ancora da UserControl. Trattandosi di una partial class, capirete bene che 'sta cosa è un pochino indigesta.
Per risolvere, è sufficiente aprire lo XAML e correggere anche questo:
<Button x:Class="VivendoByte.Emoticons.SampleButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
Ovviamente qui ho usato Button per semplicità, e per riprendere parte del codice scritto per il mio plug-in di Live Writer, ma potrebbe essere qualsiasi cosa già presente nel FW3.0. Possiamo ereditare da ListBox, da TextBlock e così via, oppure - forse meglio ancora - da una delle classi astratte da cui derivano i controlli veri e proprio (come Selector o Panel).
Non che ci voglia granchè, ma qualcuno di voi mi ha scritto privatamente con questo tipo di problema.
Su su, bastava guardare e leggere bene...