"Простой инструментарий 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. Помимо использования объекта для получения его свойства, он вообще не используется. Это может происходить из "этого", какого-то другого объекта целиком и т. Д.