2009-04-07 10 views
5

Ich habe in eine Straßensperre gelaufen scheinen. Wir verwenden MVVM mit Prism und verfügen über eine Ansicht, für die ein Ink Canvas erforderlich ist. Ich habe eine StrokeCollection erstellt, die von meinem ViewModel an die View gebunden ist. Ich bin in der Lage, die Sammlung von meinem Viewmodel zu setzen, aber Änderungen werden dem ViewModel nicht übergeben, während der Benutzer zeichnet. Gibt es eine Möglichkeit, dies zum Funktionieren zu bringen?MVVM Bindung an InkCanvas

mein Eigentum in meinem Ansichtsmodell ist wie folgt:

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

Hier meine XAML Bindungslinie ist:

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

Aus irgendeinem Grund scheint die InkCanvas benachrichtigt nie das Ansichtsmodell über jede Änderung.

Antwort

11

Das Problem mit Ihrem Ansatz ist, dass Sie davon ausgehen, InkCanvas erstellt die StrokeCollection. Es ist nicht - es fügt nur Elemente hinzu und entfernt sie. Und wenn die Sammlung nicht verfügbar ist (dh ist null), wird die Bindung fehlschlagen und die wird nichts mit ihm tun. Also:

  1. Sie benötigen einen einzigen StrokeCollection
  2. Sie erstellen müssen Sie den Inhalt der Sammlung zu übernehmen wird sich ändern, nicht die Sammlung selbst

Beispielcode:

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)); 
     } 
    } 
} 

Und XAML:

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

Ich fehlte die INotifyCollectionChanged Abschnitt. Ich hatte alles andere einschließlich der Instantiierung der StrokeCollection. Danke Kent. – cjibo

+0

Das funktioniert gut. Ich finde es interessant, dass die InkCanvas immer noch zeichnen, wenn _stokes selbst wenn sie gebunden sind, null ist. – CRice

2

Die StrokeCollection-Klasse hat ein Ereignis namens "StrokesChanged", das immer ausgelöst wird, wenn Sie etwas in der Ansicht zeichnen. Dieses Ereignis enthält die Sammlung der aktualisierten Striche.

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; 
    } 

} 

Hoffe, es hilft!