Какой должна быть модель MVVM?

Здравствуйте, у меня есть 3 вопроса о модели MVVM.

  1. Нет ли способа обойти этот избыточный PropertyChanged("PropName");
  2. Как лучше всего обернуть объекты POCO в WPF INotifyPropertyChanged, IDataErrorInfo
  3. Как мне взаимодействовать с (WPfWrapers - POCO) внутри ViewModel - через приведение или свойство...

Спасибо.


person Vladimir Nani    schedule 13.05.2011    source источник


Ответы (5)


Вот 3 ответа:

  1. Вы найдете альтернативы инициации события PropertyChanged без передачи «PropName» в виде строкового параметра в сообществе .NET. Однако все они имеют другие недостатки (например, производительность).

  2. Лучший способ — реализовать INotifyPropertyChanged и IDataErrorInfo непосредственно в модели. Это не всегда возможно. Если вам нужно обернуть классы моделей, вы можете взглянуть на Модель данных.

  3. Я не уверен, правильно ли я понимаю последний вопрос, но вот ответ. ViewModel или DataModel должны напрямую взаимодействовать с моделью. Но эти классы не должны взаимодействовать с представлением напрямую. Используйте интерфейсы (например, IView) для таких сценариев.

Дополнительную информацию можно найти здесь: Структура приложений WPF (WAF)

person jbe    schedule 13.05.2011
comment
Относительно третьего вопроса: ссылка - person Vladimir Nani; 14.05.2011

  1. Да, вы можете сделать это с помощью выражения Lamdba. Но это потребует некоторого процессорного времени (сделал несколько быстрых измерений: этот подход примерно в 200 раз медленнее, чем использование строковой константы. Имейте это в виду при использовании выражения для часто используемых POCO):

    private string ExtractPropertyName<T>( Expression<Func<T>> propertyExpresssion )
    {
        if ( propertyExpresssion == null )
        {
            throw new ArgumentNullException( "propertyExpresssion" );
        }
    
        var memberExpression = propertyExpresssion.Body as MemberExpression;
        if ( memberExpression == null )
        {
            throw new ArgumentException( "The expression is not a member access expression.", "propertyExpresssion" );
        }
    
        var property = memberExpression.Member as PropertyInfo;
        if ( property == null )
        {
            throw new ArgumentException( "The member access expression does not access a property.", "propertyExpresssion" );
        }
    
        if ( !property.DeclaringType.IsAssignableFrom( this.GetType( ) ) )
        {
            throw new ArgumentException( "The referenced property belongs to a different type.", "propertyExpresssion" );
        }
    
        var getMethod = property.GetGetMethod( true );
        if ( getMethod == null )
        {
            // this shouldn't happen - the expression would reject the property before reaching this far
            throw new ArgumentException( "The referenced property does not have a get method.", "propertyExpresssion" );
        }
    
        if ( getMethod.IsStatic )
        {
            throw new ArgumentException( "The referenced property is a static property.", "propertyExpresssion" );
        }
    
        return memberExpression.Member.Name;
    }
    
    private string myProperty;
    public string MyProperty
    {
        get
        {
            return myProperty;
        }
        set
        {
            myProperty = value;
            this.RaisePropertyChanged( ( ) => MyProperty );
        }
    }
    
    protected void RaisePropertyChanged<T>( Expression<Func<T>> propertyExpression )
    {
        var propertyName = ExtractPropertyName( propertyExpression );
        this.RaisePropertyChanged( propertyName );
    }
    
  2. Я думаю, вам не нужно их оборачивать (помимо создания соответствующей модели представления). POCO используются в качестве модели, а интерфейсы реализуются моделью представления.

  3. Этот вопрос устарел, если вы не упаковываете POCO.
person PVitt    schedule 13.05.2011
comment
Если POCO будут их реализовывать, они будут зависеть от WPF. - person Vladimir Nani; 13.05.2011
comment
INotifyPropertyChanged не имеет ничего общего с WPF. Кроме того, в качестве модели обычно используются POCO. Интерфейсы реализованы на модели представления. Так вы вообще не заденете модель. Но я обновлю свой второй ответ... - person PVitt; 13.05.2011

О первом вопросе: посмотрите этот пост< /а>

И выполните поиск в Google

Есть много способов (и обсуждений)

Мои 2 цента:

Первый и секунда

person Emond Erno    schedule 13.05.2011

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

Лично я никогда не считал это проблемой, так как ваше представление зависит как от wpf, так и от привязки к потоку, поэтому даже если используется INotifyPropertyChanged, вам все равно придется запускать событие PropertyChanged из правильного потока.

Свойства зависимостей имеют встроенную поддержку уведомлений и не требуют, чтобы wpf выполнял какое-либо отражение, поэтому они быстрее для привязки данных (но медленнее для установки/получения, хотя и в небольшом масштабе времени).

ваш сценарий может отличаться от моего, но я думаю, что стоит посмотреть :)

person aL3891    schedule 16.05.2011

Вы можете использовать новую функцию .NET 4.5 под названием "CallerMemberName", чтобы избежать жесткого кодирования имени свойства.

person lyphoon    schedule 12.09.2013