"Простой инструментарий MVVM" дочерние классы модели в C# WPF

Я использую " Простой MVVM Toolkit" (MVVM noob здесь), чтобы разработать приложение C# WPF.

У меня есть класс модели под названием A:

public class A : ModelBase<A>
{
    //properties, constructors, methods..
}

..и другой класс модели называется B который наследует от A но выставляет свойство, которое A не имеет:

public class B : A
{
    private string additionalProperty;
    public string AdditionalProperty
    {
        get { return additionalProperty; }
        set
        { 
            additionalProperty = value; 
            //NotifyPropertyChanged(m => m.AdditionalProperty); <-- problem here
        }
    }
}

Проблема приходит с прокомментированной строкой выше: лямбда в NotifyPropertyChanged не будет работать, потому что m.AdditionalProperty не существует, так как m имеет тип Aне B, Что происходит в этом случае? Я должен отметить, что NotifyPropertyChanged поставляется с инструментарием и не является пользовательской реализацией.

РЕДАКТИРОВАТЬ: Вот описание IntelliSense для NotifyPropertyChanged в B:

void ModelBaseCore<A>.NotifyPropertyChanged<TResult>(System.Linq.Expressions.Expression<Func<A,TResult>> property)

Позволяет указать лямбду для уведомления об изменении свойства

2 ответа

Решение

Проблема в том, как они реализовали ModelBase, Очевидно, они не чувствовали, что кто-то будет создавать подкласс для модели, которая ModelBaseЯ не уверен, почему они так думают.

В любом случае, проблема в том, что вы говорите ModelBase какой тип использовать для разрешения, когда вы указываете универсальный: ModelBase<A>, Чтобы обойти это, вы должны сделать довольно запутанную игру, которая выглядит довольно глупо:

public class A<T> : ModelBase<T> where T : A<T>
{
    //properties, constructors, methods..
}

public class B : A<B>
{
    private string additionalProperty;
    public string AdditionalProperty
    {
        get { return additionalProperty; }
        set
        { 
            additionalProperty = value; 
            NotifyPropertyChanged(m => m.AdditionalProperty);
        }
    }
}

Обратите внимание, что A теперь наследует от ModelBase<T> не ModelBase<A>и вы ограничиваете T быть A<T>, Тогда у вас есть B наследовать от A и укажите его общий как B (который реализует A<T>).

Это довольно запутанно, и я не уверен, почему они сделали это таким образом - возможно, потому что есть некоторые кроссплатформенные вещи, которые требуют от них этого. Если вам это не нужно для кроссплатформенной работы или, возможно, по этой причине они этого не сделали, я бы порекомендовал вам использовать что-то вроде MVVM Light для ваших нужд MVVM. Он имеет другую реализацию для NotifyPropertyChanged это не зависит от указания его собственного типа и уменьшает потребность в этом чрезмерном использовании обобщений.

Вы не ограничены свойствами параметра, передаваемого в лямбду. Вы также можете использовать свойства любого объекта, на который можно ссылаться в родительском наборе фигурных скобок (в вашем случае это метод set). Включая "это".

Вместо:

NotifyPropertyChanged(m => m.AdditionalProperty);

Пытаться:

NotifyPropertyChanged(m => this.AdditionalProperty);

Если вы перебираете источник, строковое значение переданного свойства получается из самого параметра Expression. Помимо использования объекта для получения его свойства, он вообще не используется. Это может происходить из "этого", какого-то другого объекта целиком и т. Д.

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