Telerik RadDataForm を含む UserControl があります。フォームの ItemsSource は、UserControl の ViewModel のプロパティにバインドされています。
<telerik:RadDataForm
ItemsSource="{Binding Path=viewModel.items, RelativeSource={RelativeSource AncesterType=local:MyUserControl}}"
/>
viewModel の場所:
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 のアイテムの依存関係プロパティが別のコレクションの現在のアイテムのプロパティにバインドされていることと、現在のアイテムが最初は null であるため、MyUserControl が最初に読み込まれたときにその items プロパティが null になることです。したがって、RadDataForm がバインドされている MyUserControlVM の項目プロパティも同様です。
後で、その外部コレクション内のアイテムが現在のアイテムになると、MyUserControl のアイテムの依存関係プロパティが設定され、MyUserControlVM のアイテム プロパティが設定されます。また、MyUserControlVM は notifyPropertyChanged を呼び出して、リスナーに変更が通知されるようにします。しかし、この最後は機能していません。
その後、RadDataForm を調べると、その ItemsSource プロパティはまだ null のままです。
RadDataForm が propertychanged イベントをリッスンしていないようです。これは、バインド先が最初は null だったためです。バインドされたプロパティが開始時に null ではない同様の状況では、現在のアイテムがあるアイテムから別のアイテムに変わると、このパターンは正常に機能しますが、現在のアイテムがない状態から別のアイテムがある状態になると機能しないようです。
それで、これを機能させる方法についてのアイデアはありますか?状況によっては、フォームの読み込み時にアイテムが常に値を持つようにすることはできません。最初は常に null になります。プロパティが非 null になったときに RadDataForm に通知させるにはどうすればよいですか?