【问题标题】:DataContext, DependencyProperties and BindingsDataContext、DependencyProperties 和绑定
【发布时间】:2011-06-14 13:55:17
【问题描述】:

我有一个 UserControl,我们称它为“Header”。它有一个名为 ProjectID 的 DependencyProperty,这个控件有一个 View Model,我将它设置为 DataContext:

public BillingInfoHeaderControlVM VM
{
    get
    {
        return (BillingInfoHeaderControlVM)DataContext;
    }
    set
    {
        DataContext = value;
    }

}

public static readonly DependencyProperty ProjectIDProperty =
                        DependencyProperty.Register("ProjectID", typeof(int), typeof(BillingInfoHeaderControl), new PropertyMetadata();

public int ProjectID
{
    set
    {
        SetValue(ProjectIDProperty, value);
    }
    get
    {
        return (int)GetValue(ProjectIDProperty);
    }
}

现在我要做的是将控件的 ProjectID 绑定到该控件的 ProjectID:

<controls:Header Grid.Row ="0" x:Name="Header" ProjectID="{Binding ProjectID, Mode=OneWay}"></controls:Header>

现在,当我运行它时,我在 InitializeControl() 方法中收到一个错误,指出“

找不到属性获取方法。

从我阅读的内容来看,这是因为 Binding ProjectID 与控件的数据上下文相关。当然我可以在绑定中设置 ElementName:

<controls:Header Grid.Row ="0" x:Name="Header" ProjectID="{Binding ProjectID, Mode=OneWay, ElementName=ParentControl}"></controls:Header>

但这很难看,老实说,我们不想在使用此控件时记住为该控件执行此操作。我还有什么其他选择?有没有办法将绑定的源设置为使用父级的 DataContext?

【问题讨论】:

  • ProjectID 不也是 ViewModel 的属性吗?如果没有,为什么不呢,这就是 ViewModel 的作用。

标签: c# silverlight data-binding


【解决方案1】:

我在代码中复制了你的概念,它编译并运行良好。

我在下面包含了控制代码和视图模型,以防您做一些不同的事情。

*注意:我将 viewmodel ProjectID 保留为一个简单的更新属性。:

namespace Demo1
{
    public partial class BillingInfoHeaderControl : UserControl
    {
        public BillingInfoHeaderControl()
        {
            InitializeComponent();
            this.DataContext = new BillingInfoHeaderControlVM();
        }

        public int ProjectId
        {
            get { return (int)GetValue(ProjectIdProperty); }
            set { SetValue(ProjectIdProperty, value); }
        }

        public static readonly DependencyProperty ProjectIdProperty =
            DependencyProperty.Register("ProjectId", typeof(int), typeof(BillingInfoHeaderControl),
              new PropertyMetadata(0));

    }
}

namespace Demo1
{
    public class BillingInfoHeaderControlVM : INotifyPropertyChanged
    {
        private int _projectId;
        public int ProjectId
        {
            get { return _projectId; }
            set
            {
                if (_projectId != value)
                {
                    _projectId = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("ProjectId"));
                    }
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

【讨论】:

  • 但是,如果您将此 UserControl 包含到不同的控件中,并将父控件中的某些内容绑定到此控件的属性,那么我会期望看到错误。所以我们要处理的是父控件(我们称之为 MainView)有自己的虚拟机和自己的数据上下文。然后我们要将 MainView.VM.CurrentProjectID 绑定到 Header.ProjectID:&lt;MainView&gt;&lt;controls:Header Grid.Row ="0" x:Name="Header" ProjectID="{Binding CurrentProjectID, Mode=OneWay}"&gt;&lt;/controls:Header&gt;&lt;/MainView&gt; 其中 CurrentProjectID 是 MainView 的 VM 的成员。
  • @Timothy Baldridge:我创建了一个更完整的示例,正​​如您建议的那样,在主窗口等上使用视图模型,它也可以正常工作。您可以发布更多代码和 Xaml 吗?这可能是一个非常简单的故障。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 2018-08-31
  • 1970-01-01
  • 2012-09-07
  • 2014-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多