2012-08-08 83 views
0

我有一個簡單的WPF窗口,其中包含一個帶有顏色的組合框和一個帶有該顏色的自定義畫布矩形的TabItem。在我PaintCanvas我有這樣一個DependencyProperty:DependencyProperty沒有更新

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

的PaintObject依賴屬性在XAML綁定到其相應的財產PaintViewModel:

<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從不更新。我在這裏做錯了什麼?

+0

你怎麼知道「PaintCanvas中的DependencyProperty永遠不會被更新?」?你在OnPaintObjectChanged中設置了一個斷點,還是因爲顏色沒有改變? – Clemens 2012-08-08 08:46:02

+0

@Clemens:是的,都是。 :-) – ekholm 2012-08-08 08:46:43

+0

(OnPaintObjectChanged方法是否被調用?,對不起,同時發表評論) – Timores 2012-08-08 08:47:21

回答

2

我沒有看到你改變參考PaintObject,你cahanged它(彩色)和火象PaintObject的屬性之一被改變,因爲它不是,依賴項屬性犯規刷新

作爲解決方案,您可以在XAML

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

在PaintCanvas增添色彩依賴屬性,並綁定到顏色PaintObject.Color如果你沒有忘記PaintObject調用Color屬性的NotifyPropertyChanged,PaintConvas Color屬性將被解僱是已更改

我在你的設計中看到一些亂七八糟的東西,儘量保持簡單

+0

對,除非PaintObject的屬性也是依賴項屬性或引發PropertyChanged事件,否則不起作用。 – Clemens 2012-08-08 08:57:12

+0

謝謝,就是這樣!創建一個新的繪畫對象,而不是更改顏色工作正常,我想你綁定該特定屬性的建議也將工作。假設PaintObject是一個更復雜的對象,其中有許多可能會改變的屬性,你有建議如何進行這種綁定? – ekholm 2012-08-08 09:00:58

+0

而且,你指的是什麼設計中的混亂?我應該提到兩種不同視圖模型的原因是實際上有很多TabItems看起來是一樣的。在我的真實應用程序中,我有一個以這種方式綁定到PaintViewModel的CustomControl,並且PaintObject也更加複雜。但如果事情可以做得更好,我不介意重構。 – ekholm 2012-08-08 09:07:05