si potesse … mortacci loro :-) se solo questa fosse pubblica:
image
o ci fosse un evento della classe Binding che notifica l’avvenuto data binding, questo funzionerebbe alla grande (notate le parti sottolineate):
<ListView>
   <i:Interaction.Behaviors>
      <local:ListViewColumnHeaderCommandBehavior 
         Command="{markup:AutoCommandBinding Path=ApplySort}" />
   i:Interaction.Behaviors>
ListView>
e invece non va, mentre naturalmente questo va:
<ListView>
    <i:Interaction.Behaviors>
        <local:ListViewColumnHeaderCommandBehavior 
            Command="{Binding Path=ApplySortCommand}" />
    i:Interaction.Behaviors>
ListView>
Lo scopo e i problemi
Siamo sempre li, se lavoriamo molto con M-V-VM possiamo voler ridurre il rumore al fine di eliminare dai nostri ViewModel qualcosa che è più legato all’infrastruttura piuttosto che al business.
Tipicamente con M-V-VM la sorgente dati di un binding è il ViewModel, raggiungibile attraverso la proprietà DataContext, sempre tipicamente… se avete bisogno di far operazioni strane scoprite molto rapidamente che il codice di esempio soffre di un paio di magagne non indifferenti:
  1. la proprietà DataContext è valorizzata e disponibile solo ed escusivamente dopo che il FrameworkElement è “Loaded”, mentre una Binding Expression viene valutata prima del Loaded event, e questo è un problema perchè se tutto il vostro giochetto si basa sul DataContext siete fritti :-);
  2. Un Behavior è “solo” DependencyObject quindi niente evento Loaded…;
ecco perchè IDataBindEngineClient sarebbe la soluzione di molti mali... ma non tutto il male vien per nuocere :-)
  • Il secondo problema ha una soluzione abbastanza “banale”: creare una classe base per i miei behavior che aggiunga un evento Attached che notifica quando il behavior viene “attached” al suo elemento della UI;
  • a questo punto il primo problema diventa un semplice trick: capire se siamo in un behavior e quindi agganciare l’evento Attached e solo all’atto dell’avvenuto aggancio sottoscrivere l’evento Loaded del controllo che ci interessa;
Ma…
…questo continua a non funzionare:
<DataTemplate>
   <Border BorderThickness="0,1,0,0" BorderBrush="Gainsboro" Margin="2">
      <TextBlock DataContext="{Binding Path=...}">
         <Hyperlink Command="{markup:AutoCommandBinding Path=Edit}">Modifica...Hyperlink>
      TextBlock>
   Border>
DataTemplate>
Il tutto sia che stia in un *Template sia che stia in un Popup
To be continued…
.m