2009-04-07 23 views
5

Wygląda na to, że natknąłem się na blokadę drogową. Używamy MVVM z Prismem i mamy widok, który wymaga płótna odręcznego. Stworzyłem StrokeCollection, który jest związany z moim ViewModel do widoku. Jestem w stanie ustawić kolekcję z mojego viewmodelu, ale zmiany nie zbliżają się do ViewModel podczas rysowania przez użytkownika. Czy istnieje sposób, aby to zadziałało?MVVM Wiązanie z InkCanvas

moją własnością w moim ViewModel jest następujący:

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

Tu jest mój XAML linia oprawa:

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

Z jakiegoś powodu najwyraźniej InkCanvas nigdy powiadomi ViewModel jakichkolwiek zmian.

Odpowiedz

11

Problem z twoim podejściem polega na tym, że zakładasz, że InkCanvas tworzy StrokeCollection. Nie robi - jedynie dodaje i usuwa z niej elementy. A jeśli kolekcja nie jest dostępna (tj. Jest null), wiązanie się nie powiedzie, a InkCanvas nie będzie z nim robił niczego, co jest. Więc:

  1. Musisz utworzyć jeden StrokeCollection
  2. Trzeba przyjąć zawartość kolekcji zmieni, a nie sam zbiór

Przykładowy kod:

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

I XAML:

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

Brakowało mi sekcji INotifyCollectionChanged. Miałem wszystko inne, w tym tworzenie instancji StrokeCollection. Dzięki Kent. – cjibo

+0

To działa ładnie. Uważam to za interesujące InkCanvas wciąż rysuje, gdy _stokes jest zerowy, nawet jeśli jest związany. – CRice

2

Klasa StrokeCollection ma wydarzenie o nazwie "StrokesChanged", które jest zawsze wyzwalane, gdy narysujesz coś w widoku. To wydarzenie zawiera kolekcję uaktualnień.

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

} 

Nadzieję, że to pomaga!