2013-11-22 4 views
3

У меня возникли проблемы с настройкой, которую я сейчас использую с моим приложением mvvm. Увидев несколько сообщений здесь, я чувствую, что могу сделать это немного неправильно.WPF - MVVM Viewmodel setup

У меня есть несколько моделей, которые содержат списки детей-моделей, таких как:

  • Project - Содержит список проформах
  • проформы - Содержит список отгрузок orderedItems
  • Пересылка - Содержит список Контейнеры
  • Контейнер - Содержит список пакетов

Мы не имеем какой-либо viewmo dels, которые относятся непосредственно к этой модели в настоящее время, мы вместо этого просто имеем viewmodels, которые представляют список моделей, например, у нас есть proformalistviewmodel, который просто содержит список проформ.

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

Мой вопрос: должен ли я следить за тем, что я вижу, и иметь ProjectViewModel, который содержит список проформ, и ProformaViewModel, который содержит список отправлений и упорядоченных элементов и т. Д.

Причина в том, что изначально ни одна из моделей, с которыми мы связаны, в проектах не было списка проформ, которые они были загружены отдельно через менеджеров, используя выбранный идентификатор проекта (используя реляционный db), и мы 'в настоящее время меняют модели на систему, описанную выше.

ответ

4

модель представление должна быть моделью взаимодействия пользователя для определенной области функциональности

Например, если у вас есть страница списка проектов, и пользователь может делать определенные вещи, как удалить проект, редактировать проект, печатать информацию о проекте то вы должны разработать ViewModel, содержащий данные и действия, связанные с этим интерфейсом:

например модели представления должны содержать:

* A bindable container for the project data (list of projects) 
* Actions that handle edit/delete interaction 
* An action to handle the print functionality 

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

Также может потребоваться обернуть каждый элемент данных (проект) в режиме просмотра, чтобы дополнительные свойства/действия, зависящие от взаимодействия, могли быть добавлены - например, свойство «выбрано» (представьте, что пользователь хочет многократно выбрать нагрузку проектов в целях - можно добавить выбранное свойство к ProjectViewModel, который будет обернуть каждый проект, который делает связывание легко)

вы можете в конечном итоге что-то вроде следующего:

public class ProjectOverviewViewModel 
{ 
    public IList<ProjectViewModel> Projects { get;set; } 

    public ProjectViewModel SelectedProject { get;set;} 

    public void EditSelected() 
    { 
     // Code to open edit page for the selected project 
    } 

    public void Print() 
    { 
    } 
} 

и ProjectViewModel с выбираемое имущество

public class ProjectViewModel 
{ 
    // Either put the actual data item in here and wrap it: 
    public Project Project {get;set;} 

    // Or copy properties onto the viewmodel using automapper or some other mapping framework... 
    // or manually :(
    // e.g. properties mirrored from the entity object: 
    public int ProjectId { get;set;} 
    public string ProjectName { get;set;} 

    // The selected property - now your 'Selected' logic is a function of the view/viewmodel 
    // not the entity. The entity should only be concerned with data persistence 
    public bool IsSelected {get;set;} 
} 

Вы также можете использовать комбинированные модели вместе для создания более сложных видов.Представьте, что у вас есть страница с проектами и страница «пользователи, участвующие в проекте», и вам нужна другая страница, которая показывалась как бок о бок (и разрешала вам щелкнуть проект, который обновил панель пользователей) - это возможно, составив ViewModels (путем создания другого ViewModel, который содержит два ViewModels в качестве свойств и проводов до взаимодействия между ними)

public class ProjectAndUserOverView 
{ 
    public ProjectOverviewViewModel ProjectOverview {get;set;} 
    public ProjectUsersViewModel ProjectUsers {get;set;} 

    // Code here to listen for property changes in ProjectOverview and if SelectedProject changes 
    // call ProjectUsersViewModel to refresh the data for the selected user 
} 

в конечном итоге вы просто моделирования взаимодействия с пользователем, и тем более модульным вы можете сделать это, тем легче его будет заключаться в том, чтобы сделать более удобный для обслуживания код

Есть несколько хороших фреймворков MVVM - мой личный фейс - Caliburn Micro, поскольку он делает это очень простым (он сильно использует conventio ns по умолчанию) и легко попасть.

+0

Спасибо, что на самом деле очистили некоторые запутанные, хорошо сформулированные и простые, также я узнаю ваше имя, ответив на ряд моих других вопросов. Благодаря! p.s Я уже использую caliburn.micro на основе вашего предложения в другом вопросе, и мне это нравится. – Ben

+0

Я мог бы прояснить ситуацию, если кто-то путает насчет свойства 'selected' - 'SelectedProject' в' ProjectOverviewViewModel' будет строкой, на которую пользователь нажал, чтобы они могли нажать кнопку редактирования, а свойство 'Selected' на «ProjectViewModel» будет «селектор строк» ​​в сетке для операций с несколькими выборами (например, поле флажка). Обычно у вас есть один или другой, но не оба, но вы ** можете ** иметь оба (SelectedItem в вашем элементе управления сеткой привязан к 'SelectedProject' и столбцу флажка для каждой строки, связанной с' Selected') – Charleh

1

Мои пять центов - это то, что MVVM - это образец, а не религия. Я использую его так далеко, насколько это необходимо и имеет смысл. Существует много частей, где MVVM не определен (как взаимодействие с пользователем из команд), и я много читаю о создании ViewModels только для соответствия MVVM (который раздувает дизайн и количество объектов). Я бы предположил, что вы думаете, что больше DataContext-мудрый, например: «Выбор глобального интереса хранится в глобальном DataContext, данные, связанные с Proforma, хранятся в DataContext Proforma» и т. Д., Где DataContext - это своего рода ViewModel. В конце концов, вы, вероятно, завершите их настройку с помощью пользовательского интерфейса.

+0

См. Здесь, где я всегда терялся, как делиться глобальной информацией, если я правильно слежу за вами, вы предлагаете иметь класс, который содержит глобальные данные, например активную проформу, и создание модели просмотра, которая использует это? – Ben

+0

Да - по крайней мере, это то, что я делаю по практическим соображениям. Многим частям моих приложений нужен выбор, сделанный однажды (например, Proforma в вашем случае), мои конкретные DataContexts (= VM) имеют ссылку на глобальные данные, так что я могу получить к нему доступ повсюду. Я не знаю, что MVVM должен сказать об этом, но я хорошо лажу так. –

+0

Я бы подумал, что, поскольку ViewModel технически является моделью представления, все, что не отображается каким-то образом, не является моделью просмотра. Datacontext, который вы описываете, больше похож на репозитории или службы - то, для чего была создана Dependency Injection. Но да, создание ViewModel для удовлетворения шаблона действительно работает, но оно может добавить ненужный код для вашего приложения (например, нет смысла создавать модель представления для выпадающего списка с классом данных поиска, который только когда-либо будет ключевым/значимым связанный с выпадающим списком) – Charleh

1

Вам не следует создавать ViewModels для объектов модели. Вообще говоря, ViewModel должен принадлежать UserControl. Его роль - связать ваш взгляд (ваш XAML) вместе с вашей моделью (бизнес-логикой).

В вашем случае, если я правильно понимаю, у вас есть куча классов, которые реализуют бизнес-логику (Project, Shipment и т. Д.). Ваша ViewModel будет иметь доступ к бизнес-логике и предоставить свойства для вашего вида для привязки.

+0

Итак, наличие viewmodel для datagrid (как и в настоящее время), который содержит список проформ, имеет больше смысла, чем наличие viewmodel для проекта, который содержит список проформ. – Ben

+0

@ user1412240 Это может быть языковой барьер, но я бы не сказал, что у вас есть ViewModel «для вашего объекта». ViewModel принадлежит View (то, что вы показываете пользователю). Если вы хотите отобразить некоторые атрибуты проекта, то ваша ViewModel должна иметь доступ к объекту Project. Если вы хотите отображать Proformas (я понятия не имею, что это означает), то вам лучше иметь свойство ObservableCollection в вашей ViewModel. – Marton

+0

Мартон, да, это то, что я имел в виду, профома - это просто документ, который отправляется на продажу товаров до фактического счета, его «это то, что вы намереваетесь купить, и сколько мы намерены выставить вам за это». Возникает вопрос, что ObservableCollection относится к модели Project в моей текущей настройке, поскольку проформы относятся к проекту или это плохой дизайн? – Ben

2

MVVM - это шаблон дизайна, который состоит из 3 частей: модель, ViewModel, вид. Диаграммных выглядит следующим образом: enter image description here

http://en.wikipedia.org/wiki/Model_View_ViewModel#Pattern_description

Вы используете ViewModels неправильно. Только данные для отображения должны быть в ViewModel. Ваша модель, например:

public class Project 
{ 
    public Proforma Pr{get;set;} 
} 

public class Proforma 
{ 
    public string Name{get; set;}; 
} 

Вы View для отображения проекта (я впрыснуть ViewModel конструктору, ая можно использовать DataContext, а):

public partial class ProjectView 
{ 
    private ProjectViewModel vm; 
    public ProjectView(ProjectViewModel vm) 
    { 
     this.vm = vm; 
    } 
} 

Если вы хотите отобразить имя проформы на проектном , вы должны указать его как строку в ViewModel. общественный класс ProjectViewModel { частный проект pr; public string ProformaName {get {return pr.Pr.Name;}} }

Если вы предоставляете Proforma как проформа, ваш View будет знать о модели. Это будет нарушение картины.

+0

Но im отображает список проформ в datagrid, поэтому в viewmodel есть проект, а проект имеет ObservableCollection , который предоставляет viewmodel для представления, представление никогда не узнает о модели, поскольку оно просто привязывается к списку моделей, которые viewmodel выставляет. – Ben

+1

Я не совсем согласен с этим: пока я согласен с разделом, в этом случае представление на самом деле не использует * модель. Если бы вы заменили ссылку модели в ViewModel на другой объект, если у него были такие же свойства, привязки все равно будут работать. Если вы непосредственно воздействуете на модель, введя код-код в представление, которое ** непосредственно ссылается на тип модели **, тогда модель представления/модели будет связана с нарушением шаблона.Связывание - совершенно другая игра с мячом, и создание viewmodel для связывания нескольких свойств иногда может быть излишним. – Charleh

1

У меня нет проблем с наличием моделей просмотра, которые обертывают объекты данных модели. Модели просмотра не обязательно должны быть «по одному на просмотр». Они могут представлять строку в списке или что угодно.

Сказав это, я вполне доволен привязкой к объектам модели, и я делаю это много. Единственный раз, когда я создаю модель представления для ее обертывания, - это если мне нужно дополнительное состояние для каждого объекта, которое требуется для представления.

+0

Посмотрите, что это такое, если бы я должен был создать viewmodel для обертывания объекта данных, это было бы просто ради удовлетворения шаблона и фактически бесполезно, так как 90% моделей отображаются только в datagrids – Ben

+0

Если это так, не делайте этого. Обертка элементов данных не требуется, но может быть полезна для добавления дополнительных не-сущностей, таких как «выбранный флаг строки» или «агрегированные итоги», которые не сохраняются в хранилище данных. – Charleh

+1

Нет, согласно моему второй абзац, только сделайте это, если вам нужно. Нет смысла делать это, чтобы удовлетворить некоторый пуристский шаблон MVVM. Привязка к модели прекрасна, если она дает вам все, что вам нужно. – GazTheDestroyer

Смежные вопросы