绑定到ViewModel中的初始NULL属性不会重新绑定

时间:2013-02-15 20:35:47

标签: wpf xaml binding

我有一个包含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; } }
}

在viewmodel中,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上设置items属性。并且MyUserControlVM调用notifyPropertyChanged,以便将侦听器通知更改。但这最后一次没有用。

之后,如果我检查RadDataForm,它的ItemsSource属性仍为null。

就像RadDataForm没有监听propertychanged事件一样,因为它绑定的内容最初为null。在绑定属性在开始时不为null的类似情况下,此模式在当前项目从一个项目更改为另一个项目时工作正常,但似乎无法使当前项目没有项目。

那么,关于如何使这项工作的任何想法?考虑到这种情况,我不能这样做,以便在表单加载时项目总是有一个值 - 它在开始时总是为空。当属性变为非空时,如何让RadDataForm注意到?

1 个答案:

答案 0 :(得分:0)

当我想在我的UserControl(例如自定义属性,或者像你的情况,DataContext)的根目录中引用某些东西时,我通常会给我的UserControl一个{{1 }}。然后我将此名称与Name上的ElementName属性一起使用来设置它。

Binding

由于<UserControl ... Name="TheControl"> <Grid> <TextBlock Text={Binding Path=DataContext.items, ElementName=TheControl}" /> </Grid> </UserControl> 属性,您可以互换使用它和viewModel

然而,在您的情况下,它可能实际上更简单。首先,你的代码中有一个拼写错误。它应该是DataContext(带有'o')。其次,您可能只想尝试使用AncestorType设置绑定,因为我相信您的控件已经继承了正确的{Binding Path=items}。 (但不确定最后一个。)

如果问题仍然存在,并且您怀疑它确实与最初返回DataContext的{​​{1}}属性有关,那么您始终可以使用空集合初始化items避免null

items_