Qualche giorno fa rimettendo mano ad alcuni progetti WPF, mi sono imbattuto in una di quelle cose che pur essendo semplici, mi hanno aiutato in parecchie situazioni.
Si tratta di uno UserControl che che uso come visualizzatore di Immagine rappresentativa di un oggetto, ad esempio per Collection di oggetti come ItemSource di una ListBox.
La cosa è valida anche in altre situazioni di Binding (...quindi praticamente ovunque in un'applicazione WPF...) poichè l'immagine associata ad un oggetto mostrato nelle varie parti di una maschera oltre ad essere graficamente "accattivante", a volte è proprio necessaria per la User Experience.
All'inizio ero tentato a far tutto nel codice XAML, ma spesso lo stato dell'oggetto cambia a seconda della situazione in cui si trova, l'immagine ad esso associata risulta diversa e riuscire a gestire tutto nello XAML a volte rischia di rendere illeggibile il markup.
Basta usare un'Image di WPF, con dietro un po' codice, ed è possibile dare l'immagine giusta dell'oggetto che è in Binding in quel momento:
<UserControl x:Class="WpfTest.Controlli.ImmagineControl"
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Image Name="immagine" />
</UserControl>
Il codice che lo gestisce, sostanzialmente considera una serie di situazioni in cui si trova il suo DataContext, a seconda dell'oggetto e della situazione in cui si trova (nell'esempio è se IsDisabled=true) decide che immagine visualizzare:
public partial class ImmagineControl : UserControl
{
public ImmagineControl()
{
InitializeComponent();
this.DataContextChanged += (oo, ee) => { if (DesignerProperties.GetIsInDesignMode(this))
return;
GetIcona(this.DataContext);
};
}
void GetIcona(object obj)
{
string img = "default";
if (obj is Ordine)
img = "ordine"
if (obj is Utente)
img = "utente";
if (obj is Fornitore)
img = "fornitore";
//--- posso gestire il fatto che sia disabilitato cambiano l'opacity
if ((obj as OggettoBase).IsDisabled)
immagine.Opacity = 0.4;
else
immagine.Opacity = 1;
immagine.Source = null;
string path = "/Themes/Immagini/";
Uri src = new Uri(path + img + ".png", UriKind.Relative);
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = src;
logo.EndInit();
immagine.Source = logo;
}
La cosa poi è utilizzabile anche per avere un template base per la ListView come ad esempio:
<DataTemplate x:Key="templateBase">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- il nostro controllo immagine e una textbox per il nome -->
<Controlli:ImmagineControl />
<TextBlock Text="{Binding}" Grid.Column="1" Margin="6" />
</Grid>
</DataTemplate>
<Style TargetType="ListBox">
<Setter Property="ItemTemplate" Value="{StaticResource templateBase}" />
</Style>
E quindi a Runtime ci troviamo l'effetto desiderato:
La funzione che svolge è abbastanza banale, ma dimostra che a volte con poco è possibile semplificarsi notevolmente la vita.