Pergunta

Estou tentando vincular controles em um formulário WPF a uma interface e recebo um erro de tempo de execução informando que não é possível encontrar as propriedades da interface.

Aqui está a classe que estou usando como fonte de dados:

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

Aqui está o XAML (um trecho):

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

Aqui está o código por trás (novamente, um trecho):

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

this.DataContext = person;

Observe que a classe que estou usando como fonte de dados precisa ser uma entidade porque estou usando a Injeção de Política por meio do Bloco de Aplicativo de Injeção de Política do entlib.

Estou recebendo este erro em tempo de execução:

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

Solução

Não estou familiarizado com a injeção de política do entlib, mas tenho certeza de que o seu problema está aí, e não no fato de você estar usando uma interface.
Se você fosse substituir

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

com

IPerson person = new Person();

certamente funcionaria?

Outras dicas

Não nos ligamos a quase nada além de Interfaces em nosso projeto, tudo sem problemas.O problema que você está enfrentando é devido ao entlib...mas não estou familiarizado o suficiente com o entlib para ajudá-lo nisso.O WPF pode, no entanto, vincular-se a interfaces.

Não vejo muita coisa errada com o código.Tecnicamente, você está vinculando uma instância da classe Person (ou seja, não faz sentido tentar vincular a uma interface de qualquer maneira). Não sei o que o seu método PolicyInjection.Wrap faz, mas presumo que ele retorne um valor concreto Classe de pessoa?De qualquer forma, tentei isso do meu lado e funciona bem ...

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

Eu sugiro que você analise um pouco mais essa classe PolicyInjection.Descubra se ele realmente retorna um tipo Person conforme o esperado.

Tente especificar o caminho da propriedade explicitamente no seu 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)}" /> 

Acho que o tipo gerado pela injeção de política é baseado na classe Person, mas é dinâmico e interno.Até onde eu sei, o mecanismo de vinculação de dados XAML só pode funcionar com tipos públicos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top