MVVM Binding to InkCanvas
Asked Answered
E

2

7

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.

Ejecta answered 7/4, 2009 at 23:38 Comment(0)
C
13

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}"/>
Creamcolored answered 8/4, 2009 at 8:34 Comment(2)
I was missing the INotifyCollectionChanged section. I had everything else including instantiating the StrokeCollection. Thanks Kent.Ejecta
This works nicely. I find it interesting the InkCanvas still draws when _stokes is null even when bound.Tafia
Y
4

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!

Yaelyager answered 12/8, 2015 at 14:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.