Question

J'essaie de lier des contrôles d'un formulaire WPF à une interface et j'obtiens une erreur d'exécution qui indique qu'il ne trouve pas les propriétés de l'interface.

Voici la classe que j'utilise comme source de données:

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

Voici le XAML (un extrait):

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

Voici le code derrière (encore une fois, un extrait):

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

this.DataContext = person;

Notez que la classe que j'utilise en tant que source de données doit être une entité, car j'utilise Policy Injection via le bloc d'application Policy Injection de entlib.

Je reçois cette erreur au moment de l'exécution:

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)'
Était-ce utile?

La solution

Je ne connais pas bien l'injection de politique de entlib, mais je suis à peu près sûr que votre problème réside là-dedans, et non pas le fait que vous utilisez une interface.
Si vous deviez remplacer

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

avec

IPerson person = new Person();

cela fonctionnerait-il?

Autres conseils

Dans notre projet, nous ne nous lions quasiment que des interfaces, le tout sans problème. Le problème que vous rencontrez est dû à entlib ... mais je ne connais pas assez entlib pour vous aider. WPF peut cependant se lier à des interfaces.

Je ne vois pas grand chose de mal avec le code. Techniquement, vous liez une instance de la classe Person (c’est-à-dire que tenter de vous lier à une interface n’a aucun sens.) Je ne sais pas ce que fait votre méthode PolicyInjection.Wrap, mais je suppose qu’elle renvoie un résultat concret. Classe de personne? En tout cas, je viens d’essayer ça de mon côté et ça marche très 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; }
}

Je suggérerais que vous examiniez un peu plus cette classe PolicyInjection. Déterminez si le type de personne que vous attendez est renvoyé.

Essayez de spécifier explicitement le chemin de la propriété dans votre 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)}" /> 

Je suppose que le type généré par l'injection de stratégie est basé sur la classe Person, mais qu'il est dynamique et interne. Autant que je sache, le moteur de liaison de données XAML ne peut fonctionner qu'avec des types publics.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top