WPF не может связать данные с интерфейсом? - PullRequest
2 голосов
/ 16 сентября 2008

Я пытаюсь привязать элементы управления в форме WPF к интерфейсу, и я получаю сообщение об ошибке во время выполнения, что он не может найти свойства интерфейса.

Вот класс, который я использую в качестве источника данных:

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

Вот XAML (выдержка):

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

Вот код (опять же, выдержка):

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

this.DataContext = person;

Обратите внимание, что класс, который я использую в качестве источника данных, должен быть сущностью, потому что я использую внедрение политик через блок приложения внедрения политик entlib.

Я получаю эту ошибку во время выполнения:

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 ]

3 голосов
/ 17 сентября 2008

Я не знаком с внедрением политики entlib, но я уверен, что ваша проблема кроется здесь, а не в том, что вы используете интерфейс. Если бы вы должны были заменить

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

с

IPerson person = new Person();

конечно, это будет работать?

1 голос
/ 17 сентября 2008

Мы связываем практически ничего, кроме интерфейсов в нашем проекте, все без проблем. Проблема, с которой вы столкнулись, связана с entlib ... но я недостаточно знаком с entlib, чтобы помочь вам в этом. Однако WPF может связываться с интерфейсами.

0 голосов
/ 28 января 2012

Попробуйте явно указать путь к свойству в 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)}" /> 

Я предполагаю, что тип, генерируемый внедрением политики, основан на классе Person, но является динамическим и внутренним. Насколько я знаю, механизм привязки данных XAML может работать только с открытыми типами.

0 голосов
/ 17 сентября 2008

Я не вижу ничего плохого в коде. Технически вы связываете экземпляр класса 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; }
}

Я бы посоветовал вам взглянуть на этот класс PolicyInjection немного подробнее. Узнайте, действительно ли он возвращает тип Person, как вы ожидаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...