【发布时间】:2013-01-31 21:55:20
【问题描述】:
我有一个包含 Telerik RadDataForm 的用户控件。表单的 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; } }
}
在视图模型中,items 是一个相当普通的集合:
public class MyUserControlVM : MyViewModelBase
{
private ObservableCollection<AnItem> items_;
public ObservableCollection<AnItem> items
{
get { return this.items_; }
set
{
this.items_ = value;
notifyPropertyChanged("items");
}
}
...
}
当然,MyViewModelBase 在哪里实现了 INotifyPropertyChanged。
用户控件有一个items依赖属性,设置时会在视图模型上设置匹配属性:
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 上的 items 依赖属性绑定到另一个集合的当前项的属性,并且当前项最初为 null,因此当最初加载 MyUserControl 时,它的 items 属性为 null。因此,RadDataForm 绑定到的 MyUserControlVM 上的 items 属性也是如此。
稍后,当该外部集合中的项目变为当前项目时,将设置 MyUserControl 上的项目依赖属性,并设置 MyUserControlVM 上的项目属性。 MyUserControlVM 调用 notifyPropertyChanged 以便将更改通知侦听器。但这最后一个不起作用。
之后,如果我检查 RadDataForm,它的 ItemsSource 属性仍然为 null。
这就像 RadDataForm 没有监听 propertychanged 事件,因为它最初绑定的是 null。在绑定属性在开始时不为 null 的类似情况下,当当前项从一项更改为另一项时,此模式可以正常工作,但从没有当前项到有一项似乎不起作用。
那么,关于如何完成这项工作的任何想法?在这种情况下,我不能让它在表单加载时始终具有值 - 一开始它总是为空。当属性变为非空时,如何让 RadDataForm 注意到?
【问题讨论】:
-
当
DataContext发生变化时,你会为"viewModel"解雇PropertyChanged吗? -
尝试将
Path=viewModel.items与Path=DataContext.items重调。 -
“当 DataContext 发生变化时,你会为“viewModel”触发 PropertyChanged 吗?” - DataContext 不会改变。它在 UserControl 的构造函数中设置并且永远不会改变。
-
“尝试将 Path=viewModel.items 与 Path=DataContext.items 相匹配” - 没有区别。
-
DependencyProperty.Register("itemsProperty"- 名称应该是"items",而不是"itemsProperty"。