Question

I seem to have ran into a road block. We are using MVVM with Prism and have a View that requires an Ink Canvas. I've create a StrokeCollection that is being bound from my ViewModel to the View. I am able to set the collection from my viewmodel but changes are not coming up to the ViewModel while the user draws. Is there a way to make this work?

My Property in my ViewModel is as follows:

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

Here is my XAML binding line:

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

For some reason apparently the InkCanvas never notifies the ViewModel of any change.

Was it helpful?

Solution

The problem with your approach is that you assume the InkCanvas creates the StrokeCollection. It does not - it merely adds and removes items from it. And if the collection isn't available (ie. is null), the binding will fail and the InkCanvas won't do anything with it. So:

  1. You need to create a single StrokeCollection
  2. You need to assume the contents of the collection will change, not the collection itself

Example code:

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

And XAML:

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

OTHER TIPS

StrokeCollection class have an event called "StrokesChanged" that is always fired when you draw something in the View. That event contains the collection of strokes updated.

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

}

Hope it helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top