如何在WPF中使用DataGridTemplateColumn绑定用户控件失败

我想使用来自不同程序集的User控件作为DataGridTemplateColumn。 我已经看了很多例子和问题,比如这个 , 这个 , 这个和这个 。 我无法弄清楚为什么我的代码不起作用。 这里是:

MainWindow.xaml

                  

MainWindow.xaml.cs

 namespace WpfTemplatesDemo3 { public partial class MainWindow : Window { public ObservableCollection Persons { get;set; } public MainWindow() { InitializeComponent(); this.populatePersons(); this.TableDataGrid.ItemsSource = this.Persons; } private void populatePersons() { this.Persons = new ObservableCollection(); Persons.Add(new Person { Age = 10, Name = "John0", BirthDay = new BirthDate(1, 2, 3) }); Persons.Add(new Person { Age = 11, Name = "John1", BirthDay = new BirthDate(2, 3, 4) }); Persons.Add(new Person { Age = 12, Name = "John2", BirthDay = new BirthDate(3, 4, 5) }); Persons.Add(new Person { Age = 13, Name = "John3", BirthDay = new BirthDate(4, 5, 6) }); Persons.Add(new Person { Age = 14, Name = "John4", BirthDay = new BirthDate(5, 6, 7) }); Persons.Add(new Person { Age = 15, Name = "John5", BirthDay = new BirthDate(6, 7, 8) }); } } } 

BirthDateControl.xaml

     

BirthDateControl.xaml.cs

 namespace Templates { public partial class BirthDateControl : System.Windows.Controls.UserControl { public static DependencyProperty BirthDayObjProperty = DependencyProperty.Register("BirthDayObj", typeof(BirthDate), typeof(BirthDateControl)); public BirthDate BirthDayObj { get { return ((BirthDate)GetValue(BirthDayObjProperty)); } set { SetValue(BirthDayObjProperty, value); } } public BirthDateControl() { InitializeComponent(); } } } 

Person.cs

 namespace Entities { public class Person : INotifyPropertyChanged { private string name; private int age; private BirthDate _birthDay; public string Name { get { return this.name; } set { this.name = value; this.OnPropertyChanged("Name"); this.OnPropertyChanged("Description"); } } public int Age { get { return this.age; } set { this.age = value; this.OnPropertyChanged("Age"); this.OnPropertyChanged("Description"); } } public string Description { get { return Name + "_" + Age + "_" + BirthDay.Day; } } public BirthDate BirthDay { get { return this._birthDay; } set { this._birthDay = value; this.OnPropertyChanged("BirthDate"); this.OnPropertyChanged("Description"); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propName) { if (this.PropertyChanged != null) this.PropertyChanged( this, new PropertyChangedEventArgs(propName)); } } } 

BirthDate.cs

 namespace Entities { public class BirthDate : INotifyPropertyChanged { private int day; private int month; private int year; public BirthDate(int day, int month, int year) { this.day = day; this.month = month; this.year = year; } public int Day { get { return this.day; } set { this.day = value; this.OnPropertyChanged("day"); } } public int Month { get { return this.month; } set { this.month = value; this.OnPropertyChanged("month"); } } public int Year { get { return this.year; } set { this.year = value; this.OnPropertyChanged("year"); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propName) { if (this.PropertyChanged != null) this.PropertyChanged( this, new PropertyChangedEventArgs(propName)); } } } 

如果我运行它,它将显示列,但birthdate列为空。

没有错误或警告,但这显示在输出中:

 System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate') System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate') System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate') System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate') System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate') System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate') 'WpfTemplatesDemo3.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate') The program '[16364] WpfTemplatesDemo3.exe: Managed (v4.0.30319)' has exited with code 0 (0x0). 

我无法弄清楚为什么它不会将数据绑定到用户控件。

DataGridRow具有Person对象的DataContextDataContext在您的VisualTreeinheritance,因此您的UC具有相同的上下文。 为了使您的样本工作:

  1. 从你的UC扔掉BirthDayObjProperty
  2. DataGrid丢弃这一行: DataContext="{Binding UpdateSourceTrigger=PropertyChanged}"
  3. 丢弃UC中的这一行: DataContext="{Binding RelativeSource={RelativeSource Self}}"
  4. 您的UC绑定可以像下面这样简单:

               
  5. 阅读更多关于DataContextinheritance和绑定的信息,因为你显然在滥用它们。

你必须在你的usercontrol中删除DataContext =“{Binding RelativeSource = {RelativeSource Self}}”并使用例如ElementName绑定。 否则你打破inheritance的datacontext

             

并且您的DataGridTemplateColumn不需要“新”DataContext,因为生日属性在您的person对象中