WPF не может привязать данные к интерфейсу?

Я пытаюсь привязать элементы управления в форме 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 = "[email protected]";

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)'
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
2 544
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

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

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

с

IPerson person = new Person();

конечно, это сработает?

@Robert Jeppesen: это не позволяет запускать его код PolicyInjection.

user7116 17.09.2008 01:49

Роберт прав - проблема в том, что привязка данных WPF не распознает свойства прокси-класса, которые создает PolicyInjection.Wrap. Связывание данных отлично работает без PI, поэтому мне просто нужно придумать обходной путь, который не использует его.

Matt Casto 17.09.2008 16:16

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

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

Попробуйте явно указать путь к свойству в 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 может работать только с общедоступными типами.

Другие вопросы по теме