2009-04-07 3 views
5

Mi sembra di essere imbattuto in un blocco stradale. Usiamo MVVM con Prism e abbiamo una vista che richiede una tela Ink. Ho creato una StrokeCollection vincolata dal mio ViewModel alla vista. Sono in grado di impostare la collezione dal mio viewmodel, ma le modifiche non arrivano al ViewModel mentre l'utente disegna. C'è un modo per farlo funzionare?MVVM Associazione a InkCanvas

mia proprietà nel mio ViewModel è la seguente:

private StrokeCollection _strokes; 
public StrokeCollection Signature 
{ 
    get 
    { 
     return _strokes; 
    } 
    set 
    { 
     _strokes = value; 
     OnPropertyChanged("Signature"); 
    } 
} 

Ecco il mio XAML linea di rilegatura:

<InkCanvas x:Name="MyCanvas" Strokes="{Binding Signature, Mode=TwoWay}" /> 

Per qualche ragione a quanto pare i InkCanvas non avvisa il ViewModel di ogni cambiamento.

risposta

11

Il problema con il vostro approccio è che si presuppone che lo InkCanvas crei il StrokeCollection. Non lo fa - semplicemente aggiunge e rimuove gli elementi da esso. E se la raccolta non è disponibile (ad esempio è null), l'associazione non riuscirà e il InkCanvas non eseguirà nulla con lo. Quindi:

  1. È necessario creare un unico StrokeCollection
  2. È necessario assumere il contenuto della raccolta cambierà, non la raccolta stessa

codice Esempio:

public class ViewModel : INotifyPropertyChanged 
{ 
    private readonly StrokeCollection _strokes; 

    public ViewModel() 
    { 
     _strokes = new StrokeCollection(); 
     (_strokes as INotifyCollectionChanged).CollectionChanged += delegate 
     { 
      //the strokes have changed 
     }; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public StrokeCollection Signature 
    { 
     get 
     { 
      return _strokes; 
     } 
    } 

    private void OnPropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

E XAML:

<InkCanvas Strokes="{Binding Signature}"/> 
+0

Mi mancava la sezione INotifyCollectionChanged. Ho avuto tutto il resto, inclusa la creazione di istanze di StrokeCollection. Grazie Kent. – cjibo

+0

Funziona bene. Trovo interessante che InkCanvas disegni ancora quando _stokes è nullo anche se associato. – CRice

2

La classe StrokeCollection ha un evento chiamato "StrokesChanged" che viene sempre attivato quando si disegna qualcosa nella vista. Questo evento contiene la raccolta di tratti aggiornati.

XAML:

<Grid> 
    <InkCanvas Strokes="{Binding Signature}"/> 
</Grid> 

VM:

public class TestViewModel : INotifyPropertyChanged 
{ 
    public StrokeCollection Signature { get; set; } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public TestViewModel() 
    { 
     Signature = new StrokeCollection(); 
     Signature.StrokesChanged += Signature_StrokesChanged; 
    } 

    void Signature_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e) 
    { 
     //PUT A BREAKPOINT HERE AND CHECK 
     Signature = (System.Windows.Ink.StrokeCollection)sender; 
    } 

} 

Speranza che aiuta!