2015-04-20 21 views
0

我有一個用戶控件,它繪製一個選擇矩形,其中有一個選擇屬性保存選擇矩形的值。選擇在我的主窗口中被雙向綁定,所以ViewModel可以訪問selectionRectangle值。現在我想通過改變ViewModel中的Selection值來改變selectionRectangle的大小。我試圖實現一個PropertyChangedCallback爲了做到這一點,但我沒有足夠的知識來做到這一點。我目前擁有的是一個OnSelectionChanged方法,如果我的PropertyChangedCallback被觸發,將爲我的selectionRectangle設置新的值。下面是我的代碼將對象值從MainViewModel更改爲用戶控件WPF

片斷在用戶控件依賴項屬性和方法OnSelectionChanged:

 public static readonly DependencyProperty SelectionProperty = 
     DependencyProperty.Register("Selection", typeof(Rect), typeof(CropControl), new PropertyMetadata(default(Rect))); 

    public Rect Selection 
    { 
     get 
     { 
      return (Rect)GetValue(SelectionProperty); 
     } 
     set 
     { 
      //if(this.Selection!=value) 
       SetValue(SelectionProperty, value); 
     } 
    } 

    // this is used, to react on changes from ViewModel. If you assign a 
    // new Rect in your ViewModel you will have to redraw your Rect here 
    private static void OnSelectionChanged(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs e) 
    { 
     Rect newRect = (Rect)e.NewValue; 
     Rectangle selectionRectangle = d as Rectangle; 

     if (selectionRectangle != null) 
      return; 

     selectionRectangle.SetValue(Canvas.LeftProperty, newRect.X); 
     selectionRectangle.SetValue(Canvas.TopProperty, newRect.Y); 
     selectionRectangle.Width = newRect.Width; 
     selectionRectangle.Height = newRect.Height; 
    } 

在我mainviewmodel,沒有什麼能夠獲取和設置矩形的特殊價值只是選擇屬性。

MainViewModel Selection屬性:

 private Rect selection;  //defines a Rect variable 

    //getset accessor which is bound to views UserControl that gets the dimension of the rectangle from CropControl 
    //and sets this dimension to private variable selection. The dimension will then be used to display the area 
    //cropped by the user. 
    public Rect Selection 
    { 
     get 
     { 
      return selection; 
     } 
     set 
     { 
      selection = value; 

      //// Or whatever the name of your framework/implementation the method is called 
      SetPropertyChanged("Selection"); 

      //// Cause ICommands to reevaluate their CanExecute methods 
      CommandManager.InvalidateRequerySuggested(); 
     } 
    } 

現在DependencyProperty.Register我試圖重寫它並添加FrameworkPropertyMetadata自改在另一個類中發生的,但我不知道用什麼對象的默認值,或者如果我這樣做是正確的。

public static readonly DependencyProperty SelectionProperty = 
     DependencyProperty.Register("Selection", typeof(Rect), typeof(CropControl), new PropertyMetadata(default(Rect)), new FrameworkPropertyMetadata(null,new PropertyChangedCallback(OnSelectionChanged)); 

這是一個重載的方法匹配錯誤。

回答

0

您不需要創建或註冊依賴項屬性來完成您正在嘗試執行的操作。您只需從主視圖模型中提取INotifyPropertyChanged接口的PropertyChanged事件即可。以下是我通常如何處理這個問題的一些示例代碼。

您從視圖模型中設置的 Selection
public class MainViewModel : INotifyPropertyChanged 
{ 
    // This event is for the INotifyPropertyChanged interace 
    public event PropertyChangedEventHandler PropertyChanged; 

    // This is a helper method that makes it straightforward to raise the PropertyChanged event 
    public void NotifyPropertyChanged(string propertyName) 
    { 
    PropertyChangedEventHandler handler = this.PropertyChanged; 

    if (handler != null) 
    { 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
    } 

    private Rect selection; 
    public Rect Selection 
    { 
    get 
    { 
     return this.selection; 
    } 
    set 
    { 
     this.selection = value; 

     // Alert the View that the property has been changed 
     this.NotifyPropertyChanged("Selection"); 
    } 
    } 
} 

任何時候,結合該財產的任何UI元素會自動得到更新。

+0

感謝您的快速回復,但我確實實現了這種方式,我的PropertyChangedEvent處理程序與您的完全相同。我在代碼中執行了一步,它觸發了PropertyChanged處理程序,但它不返回Selection的新值,因此它不會在我的UserControl類上觸發OnSelectionChanged。我改變選擇的大小的方式是通過創建一個矩形並將其分配給選擇:Rect newRect = new Rect(),Selection = newRect。這樣做使我的選擇值0,這應該使選擇矩形消失時,它通過我的OnSelectionChanged方法。 – mcvanta

+0

如果'selectionRectangle'變量不等於null,則注意你從'OnSelectionChanged'方法返回。這似乎是倒退,因爲你然後嘗試使用該變量。這是否會導致問題? – Michael

+0

不,因爲我逐步通過OnSelectionChanged在ViewModel和用戶控件選擇和OnSelectionChanged中放置斷點,但是選擇值在View Model上更改時,它只會轉到SetPropertyChanged並更改選擇值,但就是這樣。這裏應該發生什麼?一旦Selection在我的viewmodel中被改變,並且setPropertychanged被調用,它會通知我的UserControl OnPropertyChanged或者它是否應該通過UserControl中的Selection屬性,然後OnPropertyChanged會觸發?我只是沒有得到如何通過INotifyPropertyChanged調用OnPropertyChanged。 – mcvanta