MVVM, DataObjects в передовом опыте Catel

Я использую Catel в своем приложении. У меня есть вопросы относительно DataObjects и ViewModels — как лучше всего использовать Catel?

Сценарий 1:

У меня есть MainViewModel и MainView. В этом представлении я вызываю другое представление (DataWindow) с собственной ViewModel (SettingsViewModel) и показываю его в диалоговом окне. В этом диалоговом окне я вставляю некоторые значения настроек и сохраняю их в xml. И последнее, но не менее важное: у меня есть класс DataObject для хранения данных из диалогового окна. Здесь любой псевдокод:

MainViewModel : ViewModelBase
{
        private void OnSystemSettingsCommandExecute()
        {
            //create a new ViewModel and show as Dialog
            uiVisualizerService.ShowDialog(new SystemSettingsViewModel());
        }

    ...
}

SystemSettingsViewModel : ViewModelBase
{
        /// <summary>
        /// Gets or sets the property value.
        /// </summary>
        [Model]
        public SettingsDataObject SettingsData
        {
            get { return GetValue<SettingsDataObject>(SettingsDataProperty); }
            set { SetValue(SettingsDataProperty, value); }
        }

        /// <summary>
        ///
        /// </summary>
        public static readonly PropertyData SettingsDataProperty =   RegisterProperty("SettingsData", typeof(SettingsDataObject));


       /// <summary>
        /// It is right to define the property again here?
        /// </summary>
        [ViewModelToModel("SettingsData")]
        public string UserName
        {
            get { return GetValue<string>(UserNameProperty); }
            set { SetValue(UserNameProperty, value); }
        }

        /// <summary>
        /// Register the UserName property so it is known in the class.
        /// </summary>
        public static readonly PropertyData UserNameProperty = RegisterProperty("UserName", typeof(string));


        // Load and Save right here?
        protected override bool Save()
        {
            SettingsData.Save(@"D:\Projects\Testdata\xml\Settings.xml");

            return true;
        }

        protected override void Initialize()
        {
            SettingsData = SavableModelBase<SettingsDataObject>.Load(@"D:\Projects\Testdata\xml\Settings.xml", SerializationMode.Xml);  
        }
}


 public class SettingsDataObject : SavableModelBase<SettingsDataObject>
 {
        // Propertys 
        /// <summary>
        /// Gets or sets the property value.
        /// </summary>
        public string UserName
        {
            get { return GetValue<string>(UserNameProperty); }
            set { SetValue(UserNameProperty, value); }
        }

        /// <summary>
        /// Register the UserName property so it is known in the class.
        /// </summary>
        public static readonly PropertyData UserNameProperty = RegisterProperty("UserName", typeof(string), "MyUserName");
 }
  1. Правильно ли я должен определить свойство «UserName» в классе DataClass и в классе ViewModel? Это «обычный способ», когда я определяю свойство модели в ViewModel, а затем получаю доступ к своим свойствам данных с помощью [ViewModelToModel («SettingsData»)]?
  2. Как я могу автоматически загружать и сохранять свои объекты данных? В моем случае я переопределяю метод «Сохранить» и «Инициализировать»? Есть ли лучший способ сделать это в Catel?
  3. Теперь у меня должен быть доступ к SettingsDataObject в MainViewModel, но я не нашел способа использовать объект в других ViewModels. Каковы «лучшие методы» загрузки настроек в другие ViewModels?

person user2910295    schedule 23.10.2013    source источник


Ответы (1)


Вопрос 1)

Да, это «правильно», но полностью зависит от формы MVVM, которой вы хотите следовать. Для получения дополнительной информации прочитайте эту. Мне нравится защищать свою модель (сделать ее частной на виртуальной машине) и выставлять на виртуальной машине только те свойства, которые мне действительно нужны. Но некоторые другие люди вместо этого предпочитают напрямую привязываться к модели. Просто разное количество интерпретаций, как вы можете прочитать в статье.

Вопрос 2)

Переопределение Initialize и Save как раз и предназначено для этого, так что вы делаете это правильно!

Вопрос 3)

Когда вам нужно поделиться моделью, вы можете использовать вложенные пользовательские элементы управления для передачи модели из одной модели представления в другую. Если вам нужно получить доступ к модели во многих разных местах, может быть целесообразно зарегистрировать ее в ServiceLocator. Затем Catel может автоматически внедрить его в ваши модели представления.

// Somewhere in your code
var serviceLocator = ServiceLocator.Default;
serviceLocator.RegisterType<ISettings>(mySettings);

// Your view model constructor
public MyViewModel(ISettings mySettings)
{
  // injected here
}

Если вы хотите создать свою собственную модель представления, вы можете сделать это:

var dependencyResolver = this.GetDependencyResolver();
var viewModelFactory = dependencyResolver.Resolve<IViewModelFactory>();
var viewModel = viewModelFactory.CreateViewModel<MyViewModel>(null);

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

person Geert van Horrik    schedule 23.10.2013
comment
может быть целесообразно зарегистрировать его в ServiceLocator. Затем Catel может автоматически внедрить его в ваши модели представления. - person user2910295; 23.10.2013
comment
У вас есть пример? - person user2910295; 23.10.2013
comment
хорошо, интересно, но должна ли ViewModel реализовывать интерфейс ISettings или DataSettingsObject? В этом интерфейсе есть только геттер для общедоступных SettingsDataObject SettingsData, верно? - person user2910295; 23.10.2013
comment
Ничего из этого реализовывать не нужно. Просто определите конструктор с аргументами, и Catel позаботится об этом за вас. См. catelproject.atlassian.net/wiki/display/CTL/ для Дополнительная информация. - person Geert van Horrik; 23.10.2013
comment
SettingsDataObject mySettings = new SettingsDataObject(); var serviceLocator = ServiceLocator.Default; serviceLocator.RegisterType‹ISettings, SettingsDataObject›(); - person user2910295; 23.10.2013
comment
и чем я создаю новую модель MainViewModel (mySettings) и вставляю mySettings? - person user2910295; 23.10.2013