MVVM绑定到InkCanvas

7

我似乎遇到了一个障碍。我们正在使用MVVM和Prism,并且有一个需要Ink Canvas的View。我已经创建了一个StrokeCollection,它从我的ViewModel绑定到View。我能够从我的viewmodel设置集合,但是当用户绘制时,更改不会传递到ViewModel。有没有办法让这个工作?

我在ViewModel中的属性如下:

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

这是我的XAML绑定代码:

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

出于某种原因,似乎InkCanvas从未通知ViewModel进行任何更改。

2个回答

13

你的做法问题在于你假设 InkCanvas 创建了StrokeCollection,但实际上并不是这样 - 它只是向其中添加和移除项。如果集合不可用(即为null),绑定将失败,InkCanvas 将无法执行任何操作。所以:

  1. 你需要创建一个单独的StrokeCollection
  2. 你需要假设集合的内容会发生变化,而不是集合本身

示例代码:

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

还有XAML:

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

我漏掉了INotifyCollectionChanged部分。我已经包括了实例化StrokeCollection的所有内容。谢谢Kent。 - cjibo
这个很好用。我觉得有趣的是,即使绑定了,当_stokes为空时InkCanvas仍然会继续绘制。 - CRice

4

StrokeCollection类有一个名为“StrokesChanged”的事件,当您在视图中绘制任何内容时,该事件会始终触发。该事件包含更新后的笔画集合。

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

}

希望这能帮到你!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接