bnmc Ответов: 0

Как структура классов модели представления, модели и куда девать расчета/общей свойства


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

Я работаю с приложениями C# и WinForms уже более 5 лет и решил начать изучать WPF и MVVM для нового проекта. Это оказалось полезным, однако, похоже, люди разрываются в нескольких направлениях из-за некоторых концепций, что затрудняет исследование и поиск хорошего направления.

Должен отметить, что я делаю это в C# 6.0, .NET 4.5.2 и без использования фреймворков, таких как Prism или MvvmLight. Я бы предпочел сначала изучить основы, прежде чем применять какую-то магию.

Я опишу свой проект, чтобы проиллюстрировать вопросы.

Приложение, которое я создаю, позволяет просматривать только заявки в службу технической поддержки из базы данных SQL2000. Я только запрашиваю базу данных, но никогда не пишу в нее (для этого у нас есть отдельное приложение). У меня нет контроля над базой данных, и я не могу повлиять на переход на что-то новое. Кроме того, некоторые таблицы не очень нормализованы; дублирование данных и т. д. К сожалению, я не могу использовать Entity Framework без особых усилий. Я запрашиваю базу данных и заполняю свои настраиваемые объекты. Хотя в базе данных много таблиц, я использую четыре основных: Ticket, Event, Escalation и Rma. Таблица Ticket имеет отношение «один ко многим» с таблицами Event, Escalation и Rma; где один билет может относиться к нулю или более событиям, эскалациям или RMA. Я запрашиваю в базе данных набор билетов. Когда пользователь выбирает конкретный билет из списка, он запрашивает в базе данных остальную информацию о заявке, чтобы я мог заполнить события, эскалации и RMA.

Просмотры:
MainWindow.xaml (Окно) - Меню, TicketsView, Строка Состояния
TicketsView.xaml (UserControl) - TicketsGroupBox (текст привязан к TicketCollectionName), TicketsDataGrid, TicketView
TicketView.xaml (UserControl) - TicketGroupBox, EventsGroupBox, EventsDataGrid, EscalationsGroupBox, EscalationsDataGrid, RmasGroupBox, RmasDataGrid

Просмотр моделей:
MainWindowViewModel – TicketsViewModel, TicketsRepository, команды меню, StatusText
TicketsViewModel - TicketsRepository (передается в конструктор при создании), TicketCollectionName, ObservableCollection< Ticket>, SelectedTicket (создает TicketViewModel из объекта Ticket, переданного TicketsView.TicketsDataGrid.Элемент)
TicketViewModel – , Коллекция ObservableCollection&ЛТ авиабилет;событие&ГТ;, коллекция ObservableCollection&ЛТ;эскалации&ГТ;, коллекция ObservableCollection&ЛТ;Иов&ГТ;

Модели:
Ticket - Свойства таблицы билетов, список & lt;событие>, Список & lt;эскалация>, Список< Rma>
Event - Свойства таблицы событий
Escalation - Свойства эскалации
Rma - Свойства таблицы Rma

Дополнительный:
TicketRepository класс-взаимодействует с базой данных, заполняя список объектов тикетов.

Надеюсь, вышеизложенное дает представление о взаимоотношениях между объектами MVVM, приблизительное представление о структуре приложения.

Первая проблема, с которой я столкнулся, заключается в том, что мне нужно, чтобы свойства расчета/сводки/итога были представлены в сетках данных. Можно было бы подумать, что вы должны просто включить эти свойства В модель, однако более популярное мнение, которое я читал, состоит в том, чтобы никогда не включать эту логику в модель. Многие люди помещают их в ViewModels, что может иметь смысл. Итак, вместо того, чтобы иметь TicketsViewModel.ObservableCollection<Ticket>- Я бы так и сделал. TicketsViewModel.ObservableCollection<TicketViewModel>. В любое время SelectedItem изменившись, я бы уже имел TicketViewModel готов к работе; и не нужно будет его создавать. Сложность здесь заключается в том, что если мне нужны свойства calculation/summary/total в других трех сетках данных, которые не имеют отдельного представления/UserControls, т. е. EventsDataGrid, EscalationsDataGrid, и RmasDataGrid? Я все еще создаю их в ViewModels; или я создаю их в каком-то другом классе-оболочке для модели?

Если я следую логике выше, то структура, кажется, быстро усложняется; приходится поддерживать отдельную иерархию объектов Model и ViewModel. Если это правильный подход, то я не уверен, где вещи должны быть и когда/где я их загружу. Мне кажется, что я бы дублировал усилия, но не вижу, как еще это сделать, если мне нужны эти свойства расчета/итога. Означает ли это, что мне нужно создавать ViewModel каждый раз, когда они мне нужны? Или я иду по неверному пути?

Спасибо за любое руководство; я был бы очень признателен.

Что я уже пробовал:

Я попробовал структуру, описанную выше, но затем начал создавать ViewModels, как я обсуждаю ближе к концу.

J. Calhoun

Это трудно устранить, потому что я не вижу, как вы используете эти вещи, поэтому я не уверен в контексте вычисления, но, судя по тому, что вы помещаете эти свойства в модель представления, я предполагаю, что summary/total-это что-то вроде summary или total всей коллекции RMA/эскалаций/событий.

Кроме того, находятся ли эти сетки в отдельных представлениях? Итак, вы говорите, что в каждой модели представления вам понадобится что-то вроде Calculation {get; set;}

Способ, которым вы можете отслеживать все это, - это модель наблюдателя, которую Сунил Кумар объясняет здесь Шаблон наблюдателя в .NET[^] также Ислам Элдемери имеет хорошую реализацию Шаблоны Проектирования - Шаблон Наблюдателя[^] Таким образом, каждая модель представления, которая должна знать о событии OnChanged, может просто зарегистрироваться на это событие, чтобы все они обновились при необходимости.

Еще одна вещь, которую я не понимаю, - это билеты.модель представления.ObservableCollection & lt;ticketsviewmodel & gt; Таким образом, у вас есть несколько экземпляров одной и той же модели представления? Разве это не разрушает ваши оковы? Там должно быть только 1 TicketsViewModel, поэтому не должно быть коллекции.

bnmc

Спасибо за ответ, Джей Калхун; должно быть, я его пропустил.

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

Я решил привязываться только напрямую к ViewModels, поэтому я создаю только расчетные свойства в ViewModels. Но поскольку ViewModel действует как оболочка, и я хочу включить итоги в DataGrid в View, мне нужно иметь ObservableCollections таких вещей, как TicketsViewModel.ObservableCollection . Затем, когда пользователь выбирает один из этих элементов, изменяется SelectedItem, который привязан к TicketsViewModel.SelectedTicketViewModel. В TicketsView есть UserControl, у которого DataContext установлен на SelectedTicketViewModel; поэтому он обновляется каждый раз, когда пользователь нажимает на другой элемент. Казалось, самый простой / лучший способ сделать это.

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

0 Ответов