posts - 315, comments - 268, trackbacks - 15

My Links

News

View Pietro Libro's profile on LinkedIn

DomusDotNet
   DomusDotNet

Pietro Libro

Tag Cloud

Article Categories

Archives

Post Categories

Blogs amici

Links

WPF: PriorityBinding

 

Può capitare di dover mostrare un risultato non  immediatamente disponibile per la lettura, perché, ad esempio, il suo valore dipende da altri parametri e deve quindi essere calcolato. A tal fine, vogliamo mostrare un messaggio all’utente per indicare che l’applicazione è in esecuzione e che non è in una fase di stallo,  qualcosa di simile quando utilizziamo un UpdateProgress dell’Ajax Control Toolkit (o corrispondenti soluzioni custom) nelle nostre pagine Web. In WPF, possiamo utilizzare il PriorityBiding per fare qualcosa di simile (ma non solo). Il PriorityBinding permette di associare ad una proprietà di un elemento, un elenco di associazioni (invece di una singola associazione dati come nel “normale” Binding). Tra le associazioni, viene considerata la prima che restituisce correttamente un valore: ovvero se il Path del Binding viene risolto correttamente, se il valore restituito da un Converter è valido (sempre che ne venga utilizzato uno) o se il valore è valido per la proprietà di destinazione. Supponiamo di avere una classe Data come la seguente:

   1:      public class Data : INotifyPropertyChanged
   2:      {
   3:          private double _salary = 0;
   4:          private string _employeeName = "";
   5:          public event PropertyChangedEventHandler PropertyChanged;
   6:   
   7:          public string EmployeeName
   8:          {
   9:              get { return _employeeName; }
  10:              set
  11:              {
  12:                  _employeeName = value;
  13:                  OnPropertyChanged("EmployeeName");
  14:              }
  15:          }
  16:   
  17:          public void Calculate() { OnPropertyChanged("Salary"); }
  18:   
  19:          public double Salary
  20:          {
  21:              get
  22:              {
  23:                  _salary = 0;
  24:                  if (!string.IsNullOrEmpty(_employeeName))
  25:                  {
  26:                      //Supponiamo un'operazione che impieghi un certo tempo...
  27:                      System.Threading.Thread.Sleep(3000);
  28:   
  29:                      switch (_employeeName.ToLower())
  30:                      {
  31:                          case "pietro":
  32:                              _salary = 1000;
  33:                              break;
  34:                          case "giovanni":
  35:                              _salary = 2000;
  36:                              break;
  37:                          default:
  38:                              _salary = 0;
  39:                              break;
  40:                      }
  41:                  }
  42:                  return _salary;
  43:              }
  44:          }
  45:   
  46:          protected void OnPropertyChanged(string prop)
  47:          {
  48:              if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop));
  49:          }
  50:   
  51:          public string WaitMessage1 { get { return "Loading..."; } }
  52:   
  53:          public string WaitMessage2
  54:          {
  55:              get
  56:              {
  57:                  System.Threading.Thread.Sleep(2000);
  58:                  return "Loading...please wait";
  59:              }
  60:          }

Il cui funzionamento è abbastanza semplice: secondo del nome dell’impiegato selezionato tramite la proprietà EmployeeName quando viene richiamato Calculate() viene eseguita una notifica di cambiamento tramite OnPropertyChanged(“…”) della proprietà Salary (Ci servirà nel codice XAML). Particolare attenzione  deve essere posta alle proprietà WaitMessage1 e WaitMessage2, utilizzate nella UI per visualizzare due messaggi di attesa per l’utente: il primo subito, il secondo da visualizzare nel caso in cui l’operazione “di calcolo” si prolunghi oltre un certo tempo.

Per testare il funzionamento della classe utilizziamo una Windows WPF molto semplice:

image

Il codice XAML associato alla controllo label in cui viene visualizzato il salario dell’impiegato (calcolato), e a cui è associato il PriorityBinding è il seguente:

   1:  <Label.Content>
   2:     <PriorityBinding>
   3:        <Binding Path="Salary" Source="{StaticResource es}" IsAsync="True"  />
   4:        <Binding Path="WaitMessage2" IsAsync="True"  Source="{StaticResource es}"/>
   5:        <Binding Path="WaitMessage1" IsAsync="False" Source="{StaticResource es}"/>
   6:     </PriorityBinding>
   7:  </Label.Content>

Associamo i Binding nell’ordine in cui vogliamo vengano eseguiti: Salary, ritorna il valore dello stipendio secondo dell’impiegato specificato nel campo TextBox, WaitMessage2 è il messaggio che dovrebbe essere visualizzato se l’operazione di calcolo necessità più di due secondi, WaitMessage1 è il primo messaggio da visualizzare non appena viene fatto click sul bottone Calcola Stipendio. Affinché tutto funzioni è necessario che la proprietà IsAsync del Binding sulle proprietà Salary e WaitMessage2 sia impostato su True altrimenti l’operazione attenderà il completamento dell’associazione prima di eseguire il prossimo (eventuale) Binding (perdendo i vantaggi del PriorityBinding).

La risorsa statica es, è dichiarata a livello di Windows in questo modo:

<Window.Resources>
   <local:Data x:Key="es"/>
</Window.Resources>
Technorati Tag: ,

Print | posted on mercoledì 7 aprile 2010 14:07 | Filed Under [ WPF ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET