Pregunta

Estoy intentando vincular controles en formato WPF a una interfaz y aparece un error de tiempo de ejecución que indica que no puede encontrar las propiedades de la interfaz.

Aquí está la clase que estoy usando como fuente de datos:

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; }
}

Aquí está el XAML (un extracto):

<TextBox Name="userIdTextBox" Text="{Binding UserId}" />
<TextBox Name="userNameTextBox" Text="{Binding UserName}" />
<TextBox Name="emailTextBox" Text="{Binding Email}" />

Aquí está el código detrás (nuevamente, un extracto):

var person = PolicyInjection.Wrap<IPerson>(new Person());
person.UserId = "jdoe";
person.UserName = "John Doe";
person.Email = "jdoe@live.com";

this.DataContext = person;

Tenga en cuenta que la clase que estoy usando como fuente de datos debe ser una entidad porque estoy usando la inyección de políticas a través del bloque de aplicación de inyección de políticas de entlib.

Recibo este error en tiempo de ejecución:

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)'
¿Fue útil?

Solución

No estoy familiarizado con la inyección de políticas de entlib, pero estoy bastante seguro de que su problema radica ahí y no en el hecho de que esté utilizando una interfaz.
Si fueras a reemplazar

var person = PolicyInjection.Wrap<IPerson>(new Person());

con

IPerson person = new Person();

¿Seguramente funcionaría?

Otros consejos

Nos unimos a casi nada más que Interfaces en nuestro proyecto, todo sin problemas.El problema que estás experimentando se debe a entlib...pero no estoy lo suficientemente familiarizado con entlib para ayudarte.Sin embargo, WPF puede vincularse a interfaces.

No veo mucho mal en el código.Técnicamente estás vinculando una instancia de la clase Person (es decir, no tiene sentido intentar vincularte a una interfaz de todos modos). No sé qué hace tu método PolicyInjection.Wrap, pero supongo que devuelve un valor concreto. ¿Clase de persona?De todos modos, probé esto por mi parte y funciona bien...

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; }
}

Te sugiero que investigues un poco más esa clase PolicyInjection.Descubra si realmente devuelve un tipo de Persona como esperaba.

Intente especificar la ruta de la propiedad explícitamente en su 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)}" /> 

Supongo que el tipo generado por la inyección de políticas se basa en la clase Persona, pero es dinámico e interno.Hasta donde yo sé, el motor de enlace de datos XAML solo puede funcionar con tipos públicos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top