Какой должна быть модель MVVM? - PullRequest
2 голосов
/ 13 мая 2011

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

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

Спасибо.

Ответы [ 5 ]

3 голосов
/ 13 мая 2011

Вот 3 ответа:

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

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

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

Более подробную информацию можно найти здесь: WPF Application Framework (WAF)

1 голос
/ 13 мая 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.
0 голосов
/ 12 сентября 2013

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

0 голосов
/ 16 мая 2011

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

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

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

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

0 голосов
/ 13 мая 2011

На ваш первый вопрос: посмотрите на этот пост

И сделать поиск в Google

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

Мои 2 цента:

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

...