Domanda

Sto tentando di associare i controlli in un modulo WPF a un'interfaccia e ricevo un errore di runtime che indica che non riesce a trovare le proprietà dell'interfaccia.

Ecco la classe che sto utilizzando come origine dati:

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

Ecco il codice XAML (un estratto):

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

Ecco il codice dietro (di nuovo, un estratto):

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

this.DataContext = person;

Tieni presente che la classe che sto utilizzando come origine dati deve essere un'entità perché sto utilizzando Policy Injection tramite il Policy Injection Application Block di entlib.

Ricevo questo errore in fase di 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)'
È stato utile?

Soluzione

Non ho familiarità con l'iniezione di policy di entlib, ma sono abbastanza sicuro che il tuo problema risieda lì e non nel fatto che stai utilizzando un'interfaccia.
Se dovessi sostituire

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

con

IPerson person = new Person();

sicuramente funzionerebbe?

Altri suggerimenti

Nel nostro progetto non ci leghiamo quasi a nient'altro che alle interfacce, il tutto senza problemi.Il problema che stai riscontrando è dovuto a entlib...ma non ho abbastanza familiarità con entlib per aiutarti.WPF può, tuttavia, associarsi a Interfaces.

Non vedo molto di sbagliato nel codice.Tecnicamente stai vincolando un'istanza della classe Person (ovvero non ha senso provare ad associarsi comunque a un'interfaccia). Non so cosa fa il tuo metodo PolicyInjection.Wrap, ma suppongo che restituisca un valore concreto Classe personale?Comunque l'ho appena provato e funziona bene...

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

Ti suggerirei di esaminare un po' di più la classe PolicyInjection.Scopri se restituisce davvero il tipo Persona come previsto.

Prova a specificare esplicitamente il percorso della proprietà nel tuo 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)}" /> 

Immagino che il tipo generato dall'iniezione di policy sia basato sulla classe Person, ma è dinamico e interno.Per quanto ne so, il motore di associazione dati XAML può funzionare solo con tipi pubblici.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top