I'm trying to bind controls in a WPF form to an interface and I get a runtime error that it can't find the interface's properties.
我正在尝试将WPF表单中的控件绑定到接口,并且我得到一个运行时错误,它无法找到接口的属性。
Here's the class I'm using as a datasource:
这是我用作数据源的类:
public interface IPerson
{
string UserId { get; set; }
string UserName { get; set; }
string Email { get; set; }
}
public class Person : EntityBase, IPerson
{
public virtual string UserId { get; set; }
public string UserName { get; set; }
public virtual string Email { get; set; }
}
Here's the XAML (an excerpt):
这是XAML(摘录):
<TextBox Name="userIdTextBox" Text="{Binding UserId}" />
<TextBox Name="userNameTextBox" Text="{Binding UserName}" />
<TextBox Name="emailTextBox" Text="{Binding Email}" />
Here's the code behind (again, an excerpt):
这是后面的代码(再次,摘录):
var person = PolicyInjection.Wrap<IPerson>(new Person());
person.UserId = "jdoe";
person.UserName = "John Doe";
person.Email = "jdoe@live.com";
this.DataContext = person;
Note that the class I'm using as the data source needs to be an entity because I'm using Policy Injection through the entlib's Policy Injection Application Block.
请注意,我用作数据源的类需要是一个实体,因为我通过entlib的Policy Injection Application Block使用Policy Injection。
I'm getting this error at runtime:
我在运行时收到此错误:
System.Windows.Data Error: 16 : Cannot get 'Email' value (type 'String') from '' (type 'Person'). BindingExpression:Path=Email; DataItem='Person' (HashCode=22322349); target element is 'TextBox' (Name='emailTextBox'); target property is 'Text' (type 'String') TargetException:'System.Reflection.TargetException: Object does not match target type.
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at MS.Internal.Data.PropertyPathWorker.GetValue(Object item, Int32 level)
at MS.Internal.Data.PropertyPathWorker.RawValue(Int32 k)'
4 个解决方案
#1
3
I'm not familiar with entlib's policy injection, but I'm pretty sure that your problem lies there, and not in the fact that you're using an interface.
If you were to replace
我不熟悉entlib的策略注入,但我很确定你的问题就在那里,而不是你正在使用一个接口。如果你要更换
var person = PolicyInjection.Wrap<IPerson>(new Person());
with
IPerson person = new Person();
surely it would work?
肯定会有用吗?
#2
1
We bind to almost nothing but Interfaces in our project, all without problem. The problem you're experiencing is due to entlib... but I'm not familiar enough with entlib to help you there. WPF can, however, bind to Interfaces.
在我们的项目中,我们几乎只接触接口,所有这些都没有问题。你遇到的问题是由于entlib ...但我对entlib不太熟悉,无法帮助你。但是,WPF可以绑定到Interfaces。
#3
0
I don't see much wrong with the code. Technically you're binding an instance of the Person class (ie it doesn't make sense to try and bind to an interface anyway) I don't know what your PolicyInjection.Wrap method does, but I'm assuming it returns a concrete Person class? Anyway, I just tried this on my end and it works fine...
我没有看到代码有多大问题。从技术上讲,你是绑定Person类的一个实例(即尝试绑定到接口没有意义)我不知道你的PolicyInjection.Wrap方法做了什么,但我假设它返回一个具体的人类?无论如何,我只是尝试了这个,它工作得很好......
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
IPerson person = new Person() { FirstName = "Hovito" };
this.DataContext = person;
}
}
public class Person : IPerson
{
public virtual string FirstName { get; set; }
public string LastName { get; set; }
}
public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
I would suggest you look into that PolicyInjection class a bit more. Find out if it really does return a Person type as you expect.
我建议你再研究一下PolicyInjection类。找出它是否确实按预期返回Person类型。
#4
0
Try to specify property path explicitly in your XAML:
尝试在XAML中明确指定属性路径:
<TextBox Name="userIdTextBox" Text="{Binding (myns:IPerson.UserId)}" />
<TextBox Name="userNameTextBox" Text="{Binding (myns:IPerson.UserName)}" />
<TextBox Name="emailTextBox" Text="{Binding (myns:IPerson.Email)}" />
I guess the type generated by policy injection is based on Person class, but is dynamic and internal. As far as I know XAML data binding engine can work only with public types.
我想由策略注入生成的类型基于Person类,但是是动态的和内部的。据我所知,XAML数据绑定引擎只能用于公共类型。
#1
3
I'm not familiar with entlib's policy injection, but I'm pretty sure that your problem lies there, and not in the fact that you're using an interface.
If you were to replace
我不熟悉entlib的策略注入,但我很确定你的问题就在那里,而不是你正在使用一个接口。如果你要更换
var person = PolicyInjection.Wrap<IPerson>(new Person());
with
IPerson person = new Person();
surely it would work?
肯定会有用吗?
#2
1
We bind to almost nothing but Interfaces in our project, all without problem. The problem you're experiencing is due to entlib... but I'm not familiar enough with entlib to help you there. WPF can, however, bind to Interfaces.
在我们的项目中,我们几乎只接触接口,所有这些都没有问题。你遇到的问题是由于entlib ...但我对entlib不太熟悉,无法帮助你。但是,WPF可以绑定到Interfaces。
#3
0
I don't see much wrong with the code. Technically you're binding an instance of the Person class (ie it doesn't make sense to try and bind to an interface anyway) I don't know what your PolicyInjection.Wrap method does, but I'm assuming it returns a concrete Person class? Anyway, I just tried this on my end and it works fine...
我没有看到代码有多大问题。从技术上讲,你是绑定Person类的一个实例(即尝试绑定到接口没有意义)我不知道你的PolicyInjection.Wrap方法做了什么,但我假设它返回一个具体的人类?无论如何,我只是尝试了这个,它工作得很好......
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
IPerson person = new Person() { FirstName = "Hovito" };
this.DataContext = person;
}
}
public class Person : IPerson
{
public virtual string FirstName { get; set; }
public string LastName { get; set; }
}
public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
I would suggest you look into that PolicyInjection class a bit more. Find out if it really does return a Person type as you expect.
我建议你再研究一下PolicyInjection类。找出它是否确实按预期返回Person类型。
#4
0
Try to specify property path explicitly in your XAML:
尝试在XAML中明确指定属性路径:
<TextBox Name="userIdTextBox" Text="{Binding (myns:IPerson.UserId)}" />
<TextBox Name="userNameTextBox" Text="{Binding (myns:IPerson.UserName)}" />
<TextBox Name="emailTextBox" Text="{Binding (myns:IPerson.Email)}" />
I guess the type generated by policy injection is based on Person class, but is dynamic and internal. As far as I know XAML data binding engine can work only with public types.
我想由策略注入生成的类型基于Person类,但是是动态的和内部的。据我所知,XAML数据绑定引擎只能用于公共类型。