2009-04-07 3 views
5

로드 블록을 만났을 것 같습니다. 우리는 Prism과 함께 MVVM을 사용하고 Ink Canvas가 필요한 View를 가지고 있습니다. 내 ViewModel에서 View로 바인딩되는 StrokeCollection을 생성했습니다. 내 viewmodel에서 컬렉션을 설정할 수 있지만 사용자가 그릴 때 변경 사항이 ViewModel에 표시되지 않습니다. 이 일을 할 수있는 방법이 있습니까? 다음과 같이 내 뷰 모델에MVVM InkCanvas에 바인딩

내 재산이다 : 어떤 이유

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

분명히 InkCanvas 결코 변화의 뷰 모델은 통지하지 :

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

가 여기 내 XAML 바인딩 라인입니다.

답변

11

InkCanvasStrokeCollection을 생성한다고 가정하면 문제가 발생합니다. 단순히 항목을 추가하고 제거하기 만합니다. 컬렉션을 사용할 수없는 경우 (예 : 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

+0

이것은 잘 작동합니다. _stokes가 null 인 경우에도 InkCanvas가 여전히 재미있는 것을 알 수 있습니다. – CRice

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

} 

는 희망이 도움이!