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

1

Я использую " Simple MVVM Toolkit " (MVVM noob здесь), чтобы разработать приложение 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
        }
    }
}

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

EDIT: Вот описание IntelliSense для NotifyPropertyChanged в B:

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

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

  • 0
    @FlowFlowOverFlow это часть набора инструментов, см. ModelBase (и другие определения) набора инструментов здесь: simplemvvmtoolkit.codeplex.com/…
  • 0
    Попробуйте это: NotifyPropertyChanged((B m) => m.AdditionalProperty);
Показать ещё 3 комментария
Теги:
wpf
mvvm

2 ответа

2
Лучший ответ

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

В любом случае проблема заключается в том, что вы ModelBase какой тип использовать для разрешения, когда вы указываете общий ModelBase<A>: 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> not ModelBase<A>, и вы ограничиваете T как A<T>. Тогда у вас есть B наследовать от A и указать его общий тип B (который реализует A<T>).

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

  • 0
    спасибо @Gjeltema, я думаю, что мне придется переключиться на другой инструментарий, как предложено. MVVM Light также реализует шину сообщений? Я спрашиваю, потому что причина, по которой я попробовал Simple MVVM Toolkit, была в первую очередь из-за предложения, которое я получил от вопроса, который я задал вчера: stackoverflow.com/questions/24438728/…
  • 1
    @globetrotter DeanK в вашем другом вопросе также рекомендовал MVVMLight. Да, у него есть реализация шины сообщений. Вы также можете рассмотреть возможность использования PRISM EventAggregator или .Net EventManager (новинка в .Net 4.5) для слабой связи между виртуальными EventManager . В PRISM также есть классы, такие как ViewModelBase и ряд других вещей, которые также помогают с MVVM. Я пишу профессиональное приложение WPF для термоусадочной пленки и использую в нем MVVMLight и PRISM, и они вполне удовлетворяют наши потребности. (Между ними много общего - мы могли бы обойтись только одним из них, если бы захотели).
Показать ещё 1 комментарий
2

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

Вместо:

NotifyPropertyChanged(m => m.AdditionalProperty);

Пытаться:

NotifyPropertyChanged(m => this.AdditionalProperty);

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню