2009-04-07 77 views
5

我似乎碰到了一个路障。我们在Prism中使用MVVM,并有一个需要Ink Canvas的View。我创建了一个从我的ViewModel绑定到View的StrokeCollection。我可以从我的viewmodel设置集合,但在用户绘制时,更改不会发送到ViewModel。有没有办法做到这一点?MVVM绑定到InkCanvas

我在我的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从来没有通知任何变化的视图模型。

回答

11

您的方法存在的问题是,您认为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}"/> 
+0

我错过了INotifyCollectionChanged部分。我有其他的一切,包括实例化StrokeCollection。 谢谢肯特。 – cjibo 2009-04-08 13:15:22

2

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

} 

希望它能帮助!