МВВМ для коллекций - PullRequest
       1

МВВМ для коллекций

5 голосов
/ 10 июня 2011

Я недавно начал изучать wpf и пытаюсь использовать mvvm.

Насколько я понимаю, в mvvm ни представление, ни модель не должны знать, что существует другое.

То, что я естьПопытка сделать это показать список клиентов на экране.Но если я кодирую viewModel, как показано ниже.который похож на многие примеры, которые я вижу в сети, затем я получаю код, похожий на этот

class Customer 
{    
    public String Name {get;set;}     
    public String Address {get;set;} }
}

class MainWindowViewModel
{
    ObservableCollection<Customer> customers = new ObservableCollection<Customer>();

    public ObservableCollection<Customer> Customer 
    {
      get {return customers;}
    } 

    public MainWindowViewModel() 
    {
     //cust1 and cust2 are Customer objets
      customers.Add(cust1);
      customers.Add(cust2);
    }
}

Теперь, если я создам экземпляр моего MainWindowViewModel и задаю его какdatacontext моего MainWindowView (мое представление), и я дополнительно привязываю свойство viewmodels Customers к listBox, тогда представлению потребуется ссылка на сборку, которая содержит мои модели.

Итак, мои вопросы:

1) Допустимо ли добавлять ссылку на сборку моделей в MVVM, поскольку это будет означать, что представление знает о модели.

2) будет лучшерешение состоит в том, чтобы обернуть каждый Customer объект в CustomerViewModel и иметь MainWindowViewModel, содержащую ObservableCollection of CustomerViewModel вместо ObservableCollection of Customer .Это полностью отделит модели от вида.

Ответы [ 5 ]

3 голосов
/ 10 июня 2011
  1. Я не уверен, почему вы считаете, что проект, содержащий ваши представления, требует ссылки на ваш модельный проект?В вашем представлении нет ничего, что могло бы ссылаться на ваши модели напрямую - ваши выражения привязки в XAML связаны только с именем, и в любом случае со свойствами вашей модели представления, а не вашей модели.Это хороший вариант, если вашему представлению требуются дополнительные данные, чем предоставляет ваша модель, и нежелательно менять вашу модель.Например, при просмотре может потребоваться отображение Age типа User, но User имеет только свойство DateOfBirth.Создание UserViewModel со свойством Age было бы хорошим вариантом, если вы не хотите изменять свою модель.
2 голосов
/ 10 июня 2011

Ответы на ваши вопросы:

  1. Что плохого в представлении, ссылающемся на модель?Это абсолютно нормально, когда это упрощает код.Как раз наоборот (Модель -> Вид) - плохая практика.

  2. Вам не нужно оборачивать каждый Customer объект в CustomerViewModel когда у вас нет особых потребностей.Я бы посоветовал придерживаться прагматического подхода и сохранить простой код.

Возможно, вас заинтересует пример приложения BookLibrary для WPFApplication Framework (WAF) , который показывает сценарий, который вы описываете здесь.

0 голосов
/ 10 июня 2011

Вы определенно захотите обернуть свои модели в вид только объекты, как показано ниже:

/// <summary>
/// Business model object : Should be in your separate business model only library
/// </summary>
public class BusinessModelObject
{
    public string Prop1 { get; set; }
    public int Prop2 { get; set; }
}



/// <summary>
/// Base notifying object : Should be in your GUI library
/// </summary>
public abstract class NotifyingObject<T> : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, e);
    }


    private static readonly PropertyChangedEventArgs ModelPropertyChanged = new PropertyChangedEventArgs("Model");
    private T _model;
    public T Model
    {
        get { return _model; }
        set
        {
            _model = value;
            NotifyPropertyChanged(ModelPropertyChanged);
        }
    }
}

/// <summary>
/// Model decorator : Should be in your GUI library
/// </summary>
public class BusinessModelObjectAdapter : NotifyingObject<BusinessModelObject>
{
    public BusinessModelObjectAdapter(BusinessModelObject model)
    {
        this.Model = Model;
    }

    private static readonly PropertyChangedEventArgs Prop1PropertyChanged = new PropertyChangedEventArgs("Prop1");
    private string _prop1;
    public string Prop1
    {
        get { return Model.Prop1; }
        set
        {
            Model.Prop1 = value;
            NotifyPropertyChanged(Prop1PropertyChanged);
        }
    }

    private static readonly PropertyChangedEventArgs Prop2PropertyChanged = new PropertyChangedEventArgs("Prop2");
    private int _prop2;
    public int Prop2
    {
        get { return Model.Prop2; }
        set
        {
            Model.Prop2 = value;
            NotifyPropertyChanged(Prop1PropertyChanged);
        }
    }

    //and here you can add whatever property aimed a presenting your model without altering it at any time
}
0 голосов
/ 10 июня 2011

Шаблон MVVM аналогичен любому другому шаблону MVx (MVC, MVP, ...) в том, что он поощряет разделение интересов (SoC), что, в свою очередь, повышает удобство сопровождения / тестируемости вашего кода. Помимо обычного SoC, MVVM дает следующее:

  1. Модульное тестирование вашей логики взгляда; это потому, что вы перемещаете логику из своего представления в модель представления, делая свое представление настолько тупым, насколько это возможно.
  2. Рабочий процесс разработчика-дизайнера; поскольку представление «тупое», с XAML легче работать без логики.

Что касается видимости, то есть того, что видимо для чего, то оно строго следующее:

Model <= ViewModel <= View

Другими словами, ViewModel может видеть Модель, но Модель не может видеть ViewModel. Аналогично, View может видеть ViewModel, но не наоборот.

Поскольку ViewModel не имеет ссылки на View, он позволяет вашему коду выполняться без присутствия каких-либо компонентов представления, это разрешает (1) выше.

Цель вашей ViewModel - «придать форму» вашей модели, чтобы упростить привязку к представлению. Если ваш вид прост, тогда вполне допустимо сделать следующее:

Model <= View

Это все еще позволяет (1) модульное тестирование, (2) рабочий процесс разработчика-дизайнера.

Также хорошо использовать гибридный подход, иногда предоставляя вашу модель вашему представлению, а иногда оборачивая ее в ViewModel. Например:

http://www.scottlogic.co.uk/blog/colin/2009/08/the-mini-viewmodel-pattern/

Пожалуйста, не создавайте связку кода ViewModel, только потому, что вы думаете, что должны!

0 голосов
/ 10 июня 2011

Мы обычно создаем CustomerViewModel.Это обеспечивается нашим родовым классом CollectionViewModelBase.Это гарантирует, что каждая часть, которую использует пользовательский интерфейс, специально создана для отображения, и у нас нет никакого кода, связанного с пользовательским интерфейсом, в моделях, которые часто являются сериализуемыми POCO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...