Freeteo


Pensieri e C#dice di Matteo Raumer

WPF - uno UserControl per mostrare l'immagine di un oggetto nel binding

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.


Categoria: Tips
venerdì, 20 giu 2014 Ore. 17.06

Messaggi collegati






  • Views Home Page: 243.443
  • Views Posts: 420.903
  • Views Gallerie: 565.844
  • n° Posts: 163
  • n° Commenti: 148
Anno 2014

Anno 2013

Anno 2012

Anno 2011

Anno 2010

Anno 2009

Anno 2008

Anno 2007

Anno 2006

Anno 2005
Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003