Я работаю над боевой игрой, используя WPF. У меня есть модель Координация и ViewModel, которые я связываю с объектом Сетка. Этот ViewModel имеет свойство списка объектов Координация и описывает каждый объект как Граница с Этикетка.
Проблема в том, что данных класса Координация недостаточно для моего стиля просмотра Граница. Он имеет только свойства Ряд и Столбец, но я также хочу знать, содержит ли он Корабль, а также знать, является ли этот КорабльРаненый или затонул. В зависимости от этих значений я хочу изменить цвет Задний план моего объекта Граница.
Если я свяжу свой Граница с Корабль, то я потеряю привязку к объекту Координация (что важно, и мой Граница все еще зависит от него).
Если я переопределю свой ViewModel, чтобы он стал привязкой 1 к 1 для Граница (количество экземпляров моего ViewModel, чтобы соответствовать количеству экземпляров объектов Граница), то это будет выглядеть немного грязным и недостаточно элегантным. Но в этом случае я смогу определить все необходимые свойства, которые мой Граница использует и к которым будет привязан.
Если я создам дополнительный класс, который будет гибридом Координация и Корабль, и этот класс будет использоваться в списке как свойство ViewModel, и этот список будет связан с моим Граница, тогда я вижу две проблемы:
Если я изменю свой класс модели Координация, чтобы он содержал все необходимые свойства, у нас будет та же проблема, которую я описал в моем предыдущем «если» (первый пункт).
Если я вообще не использую привязки, то я не знаю, как лучше всего (в данном случае) реализовать связь между моим представлением Граница и моделью Координация. Также мне нужно будет получить объект Поле битвы, которому принадлежит этот Координация, чтобы иметь возможность получить оттуда все объекты Корабль. И этот подход похож на «Почему вы выбираете WPF, если вы не используете MVVM?». Я выбрал WPF, потому что люблю C#, а также потому, что WPF имеет отличную архитектуру элементов управления пользовательского интерфейса.
Я прекрасно понимаю, что WPF и MVVM могут не подойти для таких игр, как эта, и предназначены они для других целей. Но я все же хотел бы найти хорошее аккуратное решение, если оно существует.
Итак, в двух словах: как построить следующее:
Заранее большое спасибо.
Если вы выбрали это конкретное представление (список кораблей) для своего игрового состояния по уважительной причине, вам не следует менять его для представления пользовательского интерфейса. То, что вы делаете в Представлении, теоретически не должно влиять на изменение Модели.
Номер 3 — это решение, наиболее подходящее для разработки MVVM. Вы создаете настоящую модель представления, обертывающую вашу фактическую модель.
Пожалуйста, помните, что вам не нужно сохранять два состояния, ваши свойства могут зависеть от других свойств и объектов. Вы можете иметь ссылку на свой список кораблей в поле и генерировать его свойства на основе того, что он содержит, например:
public class Field
{
GameStateModel GameState { get; set; }
public int Row { get; set; }
public int Col { get; set; }
private Ship ShipOnField
{
get
{
return GameState.Ships.Where(s => s.Row == Row && s.Col == Col).FirstOrDefault();
}
}
public bool HasShip
{
get
{
return ShipOnField != null;
}
}
public bool IsShipSunk
{
get
{
return ShipOnField != null && ShipOnField.Ded;
}
}
}
Однако с этим решением есть две проблемы. Один из них — производительность. Другая — это проблема обновления представления об изменениях в модели. Вам придется либо обновлять все при каждом изменении, либо связывать изменения в модели с обновлениями ViewModel.