2012-08-08 6 views
0

색상이있는 ComboBox와 색상이있는 사각형을 그리는 사용자 정의 Canvas가 포함 된 TabItem이있는 간단한 WPF 창이 있습니다. 내 PaintCanvas에서 나는 이런 DependencyProperty에 있습니다DependencyProperty가 업데이트되지 않았습니다.

PaintObject 종속성 속성은 PaintViewModel에 해당 속성에 XAML에서 바인딩
class PaintCanvas : System.Windows.Controls.Canvas 
{ 
    public static readonly DependencyProperty PaintObjectProperty = DependencyProperty.Register(
     "PaintObject", typeof(PaintObject), typeof(PaintCanvas), new PropertyMetadata(OnPaintObjectChanged)); 


    public PaintObject PaintObject 
    { 
     get { return this.GetValue(PaintObjectProperty) as PaintObject; } 
     set 
     { 
      this.SetValue(PaintObjectProperty, value); 
     } 
    } 

    private static void OnPaintObjectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     PaintCanvas canvas = (PaintCanvas)d; 

     // Update stuff 

     canvas.InvalidateVisual(); 
    } 

    protected override void OnRender(DrawingContext dc) 
    { 
     base.OnRender(dc); 

     if (PaintObject != null) 
     { 
      dc.DrawRectangle(new SolidColorBrush(PaintObject.Color), null, new Rect(0, 0, PaintObject.Width, PaintObject.Height)); 
     } 
    } 
} 

:

:

<TabControl> 
    <TabItem DataContext="{Binding PaintViewModel}"> 
     <StackPanel > 
      <ComboBox ItemsSource="{Binding Colors}" SelectedItem="{Binding Color}" /> 
      <my:PaintCanvas Width="100" Height="100" PaintObject="{Binding PaintObject}" /> 
     </StackPanel> 
    </TabItem> 
</TabControl> 

PaintViewModel는 윈도우의 뷰 모델의 속성입니다

class MainViewModel 
{ 
    PaintViewModel paintViewModel; 

    public MainViewModel() 
    { 
     paintViewModel = new PaintViewModel(); 
    } 

    public PaintViewModel PaintViewModel 
    { 
     get { return paintViewModel; } 
    } 

    ... 
} 

실제 PaintViewModel :

class PaintViewModel : INotifyPropertyChanged 
{ 
    PaintObject paintObject; 
    ObservableCollection<Color> colors = new ObservableCollection<Color>(); 
    Color currentColor; 

    public PaintObject PaintObject 
    { 
     get { return paintObject; } 
     set { paintObject = value; RaisePropertyChanged("PaintObject"); } 
    } 

    public ObservableCollection<Color> Colors 
    { 
     get { return colors; } 
    } 

    public Color Color 
    { 
     get { return currentColor; } 
     set { 
      currentColor = value; 
      RaisePropertyChanged("Color"); 
      paintObject.Color = currentColor; 
      RaisePropertyChanged("PaintObject"); 
     } 
    } 

    // Constructors and INotifyPropertyChanged stuff... 
} 

색 콤보 상자가 제대로 작동하기 때문에 TabItem이보기 모델에 올바르게 바인딩 된 것 같습니다. 그러나 페인트 개체가 업데이트되고 RaisePropertyChanged ("PaintObject")가 호출 되더라도 PaintCanvas의 DependencyProperty는 절대로 업데이트되지 않습니다. 나는 여기서 무엇을 잘못하고 있니? 난 당신이 PaintObject에 대한 참조를 변경하는 것이 표시되지 않습니다

+0

"PaintCanvas의 DependencyProperty는 절대로 업데이트되지 않습니다"라는 것을 어떻게 알 수 있습니까? 'OnPaintObjectChanged'에 중단 점을 설정 했습니까? 아니면 단순히 색상이 변경되지 않았기 때문입니까? – Clemens

+0

@Clemens : 예, 둘 다 있습니다. :-) – ekholm

+0

(OnPaintObjectChanged 메서드는?, 미안, 동시 주석이라고도 함) – Timores

답변

2

, 당신은 그것을 (컬러) 및 PaintObject 등 화재의 특성 중 하나가 변경 cahanged, 그것이 아니므로, 종속성 속성은으로

를 새로 나던 당신이 PaintObject의 컬러 속성의 NotifyPropertyChanged를 호출하는 것을 잊지 경우 솔루션, 당신은 PaintCanvas에 컬러 종속성 속성을 추가하고 결합 색상 PaintObject.Color에 XAML

<my:PaintCanvas Width="100" Height="100" PaintObject="{Binding PaintObject}" Color={Binding PaintObject.Color} /> 

에 그리고 수 PaintConvas 컬러 속성으로 발사됩니다 변경됨

디자인에 난잡한 것을 보았습니다. 간단하게 유지하려고 시도했습니다.

+0

PaintObject의 속성이 종속성 속성이거나 PropertyChanged 이벤트를 발생시키지 않으면 올바르게 작동하지 않습니다. – Clemens

+0

고마워, 그게 다야! 색상을 변경하는 jsut 대신 새로운 페인트 객체를 만드는 것이 좋습니다. 특정 속성을 바인딩하는 제안도 효과가있을 것이라고 생각합니다. PaintObject가 변경 될 가능성이있는 많은 속성을 가진 훨씬 복잡한 객체라고 가정하면이 바인딩을 만드는 방법에 대한 제안이 있습니까? – ekholm

+0

또한, 당신이 말하는 디자인의 엉망은 무엇입니까? 두 개의 서로 다른 뷰 모델에 대한 이유는 실제로 같은 모양의 TabItem이 많이 있다는 점입니다. 내 실제 응용 프로그램에서는이 방식으로 PaintViewModel에 바인딩 된 CustomControl 있고 PaintObject 또한 더 복잡합니다. 하지만 일을 더 잘할 수 있다면 리팩토링에 신경 쓰지 않습니다. – ekholm

관련 문제