2013-02-15 26 views
0

我有一個包含Telerik RadDataForm的UserControl。表單的ItemsSource綁定到屬性上的用戶控件的視圖模型:綁定到ViewModel中最初的NULL屬性不會重新綁定

<telerik:RadDataForm 
    ItemsSource="{Binding Path=viewModel.items, RelativeSource={RelativeSource AncesterType=local:MyUserControl}}" 
    /> 

其中視圖模型是:

public partial class MyUserControl: UserControl 
{ 
    public MyUserControlVM viewModel 
    { get { return this.DataContext as MyUserControlVM; } } 
} 

內視圖模型,項目是一個相當普通的集合:

public class MyUserControlVM : MyViewModelBase 
{ 
    private ObservableCollection<AnItem> items_; 
    public ObservableCollection<AnItem> items 
    { 
     get { return this.items_; } 
     set 
     { 
      this.items_ = value; 
      notifyPropertyChanged("items"); 
     } 
    } 

    ... 
} 

而且當然,MyViewModelBase實現INotifyPropertyChanged。

用戶控件有一個項目依賴屬性,當它被設置,它設置在視圖模型匹配性質:

public partial class MyUserControl : UserControl 
{ 
    public ObservableCollection<AnItem> items 
    { 
     get { return GetValue itemsProperty as ObservableCollection<AnItem>; } 
     set { SetValue(itemsProperty, value); } 
    } 
    public static readonly DependencyProperty itemsProperty = 
     DependencyProperty.Register("items", 
     typeof(ObservableCollection<AnItem>), 
     typeof(MyUserControl), new PropertyMetadata(
        new PropertyChangedCallback(itemsPropertyChanged))); 
    private static void itemsPropertyChanged(DependencyObject d, 
      DependencyPropertyChangedEventArgs e) 
    { 
     MyUserControl myUserControl = d as MyUserControl; 
     ObservableCollection<AnItem> items = 
      e.NewValue as ObservableCollection<AnItem>; 
     if (myUserControl != null && myUserControl.viewModel != null) 
      myUserControl.viewModel.items = items; 
    } 
} 

所有這一切似乎非常簡單,如果有點乏味。

問題是MyUserControl上的項目依賴項屬性綁定到另一個集合的當前項目的屬性,並且當前項目最初爲空,所以當MyUserControl最初加載時,其項目屬性爲null。因此,與RadDataForm綁定的MyUserControlVM上的items屬性也是如此。

稍後,當該外部集合中的項目變爲當前項時,將設置MyUserControl上的項目依賴項屬性,並設置MyUserControlVM上的項目屬性。 MyUserControlVM調用notifyPropertyChanged,這樣監聽器會被告知這個改變。但這最後一個不起作用。

之後,如果我檢查RadDataForm,它的ItemsSource屬性仍然爲空。

這就好像RadDataForm沒有監聽propertychanged事件,因爲它綁定的內容最初是空的。在開始時綁定屬性不爲空的類似情況下,此模式可以正常工作,因爲當前項目從一個項目更改爲另一個項目,但似乎無法從沒有當前項目變爲有效項目。

那麼,有關如何使這項工作的任何想法?根據具體情況,我不能在表單加載時使項目始終具有值 - 在開始時它總是爲空。如何讓RadDataForm在屬性變爲非空時注意到?

+0

當'DataContext'發生變化時,是否爲''viewModel''激發'PropertyChanged'? – user7116 2013-02-15 20:38:53

+0

嘗試用'Path = DataContext.items'重置'Path = viewModel.items'。 – 2013-02-15 21:06:09

+0

「當DataContext更改時,是否爲」viewModel「觸發PropertyChanged?」 - DataContext不會更改。它在UserControl的構造函數中設置並且永遠不會改變。 – 2013-02-15 21:19:34

回答

0

當我想在我的UserControl(例如自定義屬性,或者在您的情況下,DataContext)的根目錄引用某些內容時,我通常會給我的UserControl一個Name。然後,我使用此名稱和Binding上的ElementName屬性進行設置。

<UserControl 
    ... 
    Name="TheControl"> 

    <Grid> 
     <TextBlock Text={Binding Path=DataContext.items, ElementName=TheControl}" /> 
    </Grid> 
</UserControl> 

由於viewModel屬性,你可以使用和DataContext互換。

但是,在你的情況下它可能實際上更簡單。首先,您的代碼中存在拼寫錯誤。它應該是AncestorType(帶有'o')。其次,您可能想嘗試僅使用{Binding Path=items}設置綁定,因爲我相信您的控件已經繼承了正確的DataContext。 (不知道最後一個,但。)

如果問題仍然存在,並且懷疑它其實有事情做與items的財產返還null最初,你總是可以用一個空的集合初始化items_避免null

private ObservableCollection<AnItem> items_ = new ObservableCollection<AnItem>(); 
+0

如果在使用usercontrol時使用XAML指定了ax:Name,那麼可能會覆蓋Name:但是在一個快速測試中,似乎沒有 – 2013-02-15 22:48:56

+0

在RadDataForm的上下文中使用{Binding Path = items}會綁定到RadDataForm的DataContext中的一個屬性,這與我的UserControl的DataContext不一樣。 – 2013-02-15 22:54:18

+0

你說「表單的ItemsSource綁定到UserControl的ViewModel上的一個屬性「,我認爲它們共享相同的數據上下文。我錯過了什麼? – 2013-02-15 23:02:51

相關問題