Ах, ваша редакция проясняет все достаточно, чтобы оправдать новый ответ. Вот оно:
Вся причина, по которой модель вида называется "моделью вида", заключается в том, что она действительно модель . Да, обычно он не сохраняется на диск (хотя может), но в нем есть все другие аспекты модели: он хранит пользовательские данные, он связан с видом, у него нет ссылок на вид и т. Д. .
В вашем случае у вас есть набор настроек, которые вы хотите связать с каждой комбинацией {пользователь, виджет}. Эта коллекция настроек должна быть сохранена и доступна в каждом из ваших представлений. Концептуально это отдельный объект модели: это не виджет, это не пользователь и он не зависит от вида. Называете ли вы это «моделью представления» или просто «моделью», это, прежде всего, вопрос терминологии. Как бы вы ни хотели его классифицировать, давайте назовем сам объект UserWidgetSettings
.
Где-то у вас будет резервное хранилище, в котором вы сохраните объекты UserWidgetSettings. Это может быть в локальном файле, в реестре или в той же базе данных, где хранятся ваши объекты User и Widget. Для обсуждения предположим, что вы храните их отдельно от объектов User и Widget, и у вас есть класс, который сохраняет их:
public class UserWidgetSettings : DependencyObject // or INotifyPropertyChanged
{
public bool AutoScroll { get { return (bool)GetValue(AutoScrollProperty); } set { SetValue(AutoScrollPropery, value); } }
public static readonly DependencyProperty AutoScrollProperty = DependencyProperty.Register("AutoScroll", typeof(bool), typeof(UserWidgetSettings));
... more settings ...
}
public class UserWidgetSettingsStorage
{
public static readonly UserWidgetSettingsStorage Current = new UserWidgetSettingsStorage();
private Dictionary<Pair<User,Widget>, WeakReference<UserWidgetSettings>> _cache;
public UserWidgetSettings GetSettings(User user, Widget widget)
{
... code to retrieve settings from file, registry, etc ...
}
public void Savechanges()
{
... code to iterate the cache and save back changes to UserWidgetSettings objects ...
... called on Application.OnExit and perhaps other times ...
}
}
Теперь вашим ViewModels, используемым представлениями, просто нужно свойство для доступа к настройкам:
public class SomeViewModel
{
public Widget Widget { get; set; }
... regular view model code ...
public UserWidgetSettings UserSettings
{
get
{
return UserWidgetSettingsStorage.Current.GetSettings(
MyApp.CurrentUser, Widget);
}
}
}
По вашему мнению, вы можете использовать настройки следующим образом:
<SomeControl AutoScroll="{Binding UserSettings.AutoScroll}" />
А ваш флажок для управления выглядит так:
<CheckBox IsChecked="{Binding UserSettings.AutoScroll}" />
Примечание: я обнаружил, что в среднем только около 20% моих просмотров действительно нуждаются в собственной модели представления. Остальные могут использовать общие свойства, предоставляемые самой моделью. Если вы обнаружите, что создаете отдельную модель представления для каждого отдельного представления, что-то может быть неправильно. Возможно, вы захотите взглянуть и посмотреть, есть ли какие-то вещи, которые вы делаете в модели представления, которые имеют такой же или больший смысл в самой модели. Итог: хорошо спроектированные объекты моделей могут значительно сократить объем кода в приложении WPF.