Reputation: 4667
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.
Upvotes: 7
Views: 5174
Reputation: 105
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!
Upvotes: 4
Reputation: 178630
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:
StrokeCollection
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}"/>
Upvotes: 13