如何解决 WPF 中的 "Binding Expression Path error"?
How to resolve a "Binding Expression Path error" in WPF?
我正在将可观察的模型对象集合绑定到数据网格。但是,当我将绑定设置为集合时,我收到一个指向人物的路径错误。
在调试此问题时,我检查了 CustomerModel 中的 public 属性在 DataGrid 绑定中是否正确命名。而且返回给模型的集合不是空的。我还检查了视图后面的代码中是否正确设置了数据上下文。
由于我在 xaml..
中指定绑定路径的方式,我认为这可能是一个错误
绑定错误的完整细节如下,每个字段:
System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName' property not found on 'object' ''MainViewModel' (HashCode=55615518)'. BindingExpression:Path=FirstName; DataItem='MainViewModel' (HashCode=55615518); target element is 'TextBox' (Name='fNameTbx'); target property is 'Text' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'LastName' property not found on 'object' ''MainViewModel' (HashCode=55615518)'. BindingExpression:Path=LastName; DataItem='MainViewModel' (HashCode=55615518); target element is 'TextBox' (Name='lNameTbx'); target property is 'Text' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'Email' property not found on 'object' ''MainViewModel' (HashCode=55615518)'. BindingExpression:Path=Email; DataItem='MainViewModel' (HashCode=55615518); target element is 'TextBox' (Name='emailTbx'); target property is 'Text' (type 'String')
任何人都可以指出正确的方向,以便进一步调试吗?
DataGrid绑定路径和来源设置如下:
<DataGrid Name="infogrid"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="1"
Grid.ColumnSpan="3"
AutoGenerateColumns="False"
ItemsSource="{Binding Customers}"
SelectedItem="{Binding SelectedCustomer}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Customers.Id}" Header="ID" />
<DataGridTextColumn Binding="{Binding Customers.FirstName}" Header="First Name" />
<DataGridTextColumn Binding="{Binding Customers.LastName}" Header="Last Name" />
<DataGridTextColumn Binding="{Binding Customers.Email}" Header="Email" />
</DataGrid.Columns>
</DataGrid>
视图模型包含一个名为 Customers 的 CustomerModel 类型的 Observable 集合。这就是我将 DataGrid ItemSource 设置为的内容。 (为了便于阅读,我从 VM 中删除了其他代码)
namespace MongoDBApp.ViewModels
{
class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private ICustomerDataService _customerDataService;
public MainViewModel(ICustomerDataService customerDataService)
{
this._customerDataService = customerDataService;
QueryDataFromPersistence();
}
private ObservableCollection<CustomerModel> customers;
public ObservableCollection<CustomerModel> Customers
{
get
{
return customers;
}
set
{
customers = value;
RaisePropertyChanged("Customers");
}
}
private void QueryDataFromPersistence()
{
Customers = _customerDataService.GetAllCustomers().ToObservableCollection();
}
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
这些是 CustomerModel 中的字段,所以不确定为什么在绑定期间找不到属性:
public class CustomerModel : INotifyPropertyChanged
{
private ObjectId id;
private string firstName;
private string lastName;
private string email;
[BsonElement]
ObservableCollection<CustomerModel> customers { get; set; }
/// <summary>
/// This attribute is used to map the Id property to the ObjectId in the collection
/// </summary>
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("firstName")]
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
RaisePropertyChanged("FirstName");
}
}
[BsonElement("lastName")]
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
RaisePropertyChanged("LastName");
}
}
[BsonElement("email")]
public string Email
{
get
{
return email;
}
set
{
email = value;
RaisePropertyChanged("Email");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
这是在视图后面的代码中设置数据上下文的方式:
public partial class MainView : Window
{
private MainViewModel ViewModel { get; set; }
private static ICustomerDataService customerDataService = new CustomerDataService(CustomerRepository.Instance);
public MainView()
{
InitializeComponent();
ViewModel = new MainViewModel(customerDataService);
this.DataContext = ViewModel;
}
}
异常表明 DataBinding 引擎正在 MainViewModel
而不是 CustomerModel
上查找字段 FirstName
、LastName
等。
您无需在列的各个绑定表达式中指定 属性 Customers
:
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="ID" />
<DataGridTextColumn Binding="{Binding FirstName}" Header="First Name" />
<DataGridTextColumn Binding="{Binding LastName}" Header="Last Name" />
<DataGridTextColumn Binding="{Binding Email}" Header="Email" />
</DataGrid.Columns>
这些绑定错误与您的 DataGrid 无关。
它们表示您在名称 fNameTbx
、lNameTbx
和 emailTbx
的某处有 3 个文本框。 DataGrid 不会生成其名称为 属性 的项,因此它不是导致这些绑定错误的项。
尝试阅读绑定错误时,最好用分号将它们分开并向后阅读,如 here 所示。
例如,
System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName' property not found on 'object' ''MainViewModel' (HashCode=55615518)'. BindingExpression:Path=FirstName; DataItem='MainViewModel' (HashCode=55615518); target element is 'TextBox' (Name='fNameTbx'); target property is 'Text' (type 'String')
也可以读作
- 目标 属性 是 'Text'(类型 'String')
- 目标元素是'TextBox'(名称='fNameTbx');
- DataItem='MainViewModel' (哈希码=55615518);
- BindingExpression 路径错误:'FirstName' 属性 未在 'object' ''MainViewModel' (HashCode=55615518)' 上找到。 BindingExpression:Path=名字;
意思是你有
<TextBox Name="fNameTbx" Text="{Binding FirstName}" />
其中此 TextBox 的 DataContext
类型为 MainViewModel
。 MainViewModel
没有 FirstName
的 属性。
我建议在您的项目中搜索这些名称,或者您可以使用 Snoop 之类的工具在运行时调试数据绑定和 DataContext 问题。
当我在 DataTemplate 中使用 TextBlock 文本绑定时,我遇到了同样的问题,我最终不得不这样做:
Text={Binding DataContext.SuccessTxt}
让它正常工作。尝试在 属性 前面添加 "DataContext.",看看是否可行。
public Window()
{
this.DataContext = this;
InitializeComponent();
}
public string Name {get;set;}
//xaml
<TextBlock Text="{Binding Name}"/>
this.DataContext = this;
在 InitializeComponent();
之前
(DataContext 需要在 InitializeComponent()
中加载 xaml 之前可用)
属性 Name
应该是 public
和 { get; }
(如果是private则wpf无法访问)
我正在将可观察的模型对象集合绑定到数据网格。但是,当我将绑定设置为集合时,我收到一个指向人物的路径错误。
在调试此问题时,我检查了 CustomerModel 中的 public 属性在 DataGrid 绑定中是否正确命名。而且返回给模型的集合不是空的。我还检查了视图后面的代码中是否正确设置了数据上下文。
由于我在 xaml..
中指定绑定路径的方式,我认为这可能是一个错误绑定错误的完整细节如下,每个字段:
System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName' property not found on 'object' ''MainViewModel' (HashCode=55615518)'. BindingExpression:Path=FirstName; DataItem='MainViewModel' (HashCode=55615518); target element is 'TextBox' (Name='fNameTbx'); target property is 'Text' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'LastName' property not found on 'object' ''MainViewModel' (HashCode=55615518)'. BindingExpression:Path=LastName; DataItem='MainViewModel' (HashCode=55615518); target element is 'TextBox' (Name='lNameTbx'); target property is 'Text' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'Email' property not found on 'object' ''MainViewModel' (HashCode=55615518)'. BindingExpression:Path=Email; DataItem='MainViewModel' (HashCode=55615518); target element is 'TextBox' (Name='emailTbx'); target property is 'Text' (type 'String')
任何人都可以指出正确的方向,以便进一步调试吗?
DataGrid绑定路径和来源设置如下:
<DataGrid Name="infogrid"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="1"
Grid.ColumnSpan="3"
AutoGenerateColumns="False"
ItemsSource="{Binding Customers}"
SelectedItem="{Binding SelectedCustomer}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Customers.Id}" Header="ID" />
<DataGridTextColumn Binding="{Binding Customers.FirstName}" Header="First Name" />
<DataGridTextColumn Binding="{Binding Customers.LastName}" Header="Last Name" />
<DataGridTextColumn Binding="{Binding Customers.Email}" Header="Email" />
</DataGrid.Columns>
</DataGrid>
视图模型包含一个名为 Customers 的 CustomerModel 类型的 Observable 集合。这就是我将 DataGrid ItemSource 设置为的内容。 (为了便于阅读,我从 VM 中删除了其他代码)
namespace MongoDBApp.ViewModels
{
class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private ICustomerDataService _customerDataService;
public MainViewModel(ICustomerDataService customerDataService)
{
this._customerDataService = customerDataService;
QueryDataFromPersistence();
}
private ObservableCollection<CustomerModel> customers;
public ObservableCollection<CustomerModel> Customers
{
get
{
return customers;
}
set
{
customers = value;
RaisePropertyChanged("Customers");
}
}
private void QueryDataFromPersistence()
{
Customers = _customerDataService.GetAllCustomers().ToObservableCollection();
}
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
这些是 CustomerModel 中的字段,所以不确定为什么在绑定期间找不到属性:
public class CustomerModel : INotifyPropertyChanged
{
private ObjectId id;
private string firstName;
private string lastName;
private string email;
[BsonElement]
ObservableCollection<CustomerModel> customers { get; set; }
/// <summary>
/// This attribute is used to map the Id property to the ObjectId in the collection
/// </summary>
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("firstName")]
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
RaisePropertyChanged("FirstName");
}
}
[BsonElement("lastName")]
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
RaisePropertyChanged("LastName");
}
}
[BsonElement("email")]
public string Email
{
get
{
return email;
}
set
{
email = value;
RaisePropertyChanged("Email");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
这是在视图后面的代码中设置数据上下文的方式:
public partial class MainView : Window
{
private MainViewModel ViewModel { get; set; }
private static ICustomerDataService customerDataService = new CustomerDataService(CustomerRepository.Instance);
public MainView()
{
InitializeComponent();
ViewModel = new MainViewModel(customerDataService);
this.DataContext = ViewModel;
}
}
异常表明 DataBinding 引擎正在 MainViewModel
而不是 CustomerModel
上查找字段 FirstName
、LastName
等。
您无需在列的各个绑定表达式中指定 属性 Customers
:
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="ID" />
<DataGridTextColumn Binding="{Binding FirstName}" Header="First Name" />
<DataGridTextColumn Binding="{Binding LastName}" Header="Last Name" />
<DataGridTextColumn Binding="{Binding Email}" Header="Email" />
</DataGrid.Columns>
这些绑定错误与您的 DataGrid 无关。
它们表示您在名称 fNameTbx
、lNameTbx
和 emailTbx
的某处有 3 个文本框。 DataGrid 不会生成其名称为 属性 的项,因此它不是导致这些绑定错误的项。
尝试阅读绑定错误时,最好用分号将它们分开并向后阅读,如 here 所示。
例如,
System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName' property not found on 'object' ''MainViewModel' (HashCode=55615518)'. BindingExpression:Path=FirstName; DataItem='MainViewModel' (HashCode=55615518); target element is 'TextBox' (Name='fNameTbx'); target property is 'Text' (type 'String')
也可以读作
- 目标 属性 是 'Text'(类型 'String')
- 目标元素是'TextBox'(名称='fNameTbx');
- DataItem='MainViewModel' (哈希码=55615518);
- BindingExpression 路径错误:'FirstName' 属性 未在 'object' ''MainViewModel' (HashCode=55615518)' 上找到。 BindingExpression:Path=名字;
意思是你有
<TextBox Name="fNameTbx" Text="{Binding FirstName}" />
其中此 TextBox 的 DataContext
类型为 MainViewModel
。 MainViewModel
没有 FirstName
的 属性。
我建议在您的项目中搜索这些名称,或者您可以使用 Snoop 之类的工具在运行时调试数据绑定和 DataContext 问题。
当我在 DataTemplate 中使用 TextBlock 文本绑定时,我遇到了同样的问题,我最终不得不这样做:
Text={Binding DataContext.SuccessTxt}
让它正常工作。尝试在 属性 前面添加 "DataContext.",看看是否可行。
public Window()
{
this.DataContext = this;
InitializeComponent();
}
public string Name {get;set;}
//xaml
<TextBlock Text="{Binding Name}"/>
this.DataContext = this;
在 InitializeComponent();
之前
(DataContext 需要在 InitializeComponent()
中加载 xaml 之前可用)
属性 Name
应该是 public
和 { get; }
(如果是private则wpf无法访问)