2013-07-08 7 views
1

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

У меня есть NewMessageWindow, который показан командой

private ICommand newMessageCommand; 
    public ICommand NewMessageCommand 
    { 
     get 
     { 
      if (newMessageCommand == null) 
       newMessageCommand = new RelayCommand(() => 
       { 
        new NewMessageWindow().Show(); 
       }); 
      return newMessageCommand; 
     } 
    } 

Там может быть несколько NewMessageWindows и каждый из них должен иметь отдельный ViewModel. Но я заметил, когда открываю несколько окон, и если я что-то меняю в них, это затрагивает все окна. Например, когда я изменяю combobox, тогда значения combox изменяются во всех окнах.

Как этого избежать? Как открыть несколько окон с seprate viewmodels, которые не повлияют друг на друга?

Объекты, которые меняются: ObservableCollections, которые обязательны для просмотра.

Edit:

Это как ViewLocator выглядит

public NewMessageWindowModel NewMessage 
    { 
     get 
     { 
      return ServiceLocator.Current.GetInstance<NewMessageWindowModel>(); 
     } 
    } 

и в конструкторе

SimpleIoc.Default.Register<NewMessageWindowModel>(); 

Это как вяжущие выглядит так:

DataContext="{Binding NewMessage, 
          Source={StaticResource Locator}}" 

Я фиксированный probl em с

ServiceLocator.Current.GetInstance<NewMessageWindowModel(System.Guid.NewGuid().ToString()); 

но я читал, что старые экземпляры кэшируются. Как избавиться от них?

+1

У каждого вида есть своя модель? Если все представления имеют одну и ту же модель просмотра, то ваша функция INofifyPropertyChanged (или аналогичная реализация MVVM) будет уведомлять обо всех окнах и соответственно изменять их. –

+0

как я могу проверить его? Все они расширяются 'ViewModelBase' – Robert

+0

Не видя больше кода, сложно сказать; Я предполагаю, что ваши взгляды - это окна XAML, устанавливаете ли вы каждый файл datacontext для другой модели представления? –

ответ

1

SimpleIoC из MVVM Light не создает новую виртуальную машину за один звонок с ServiceLocator.Current.GetInstance<...>();

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

В вашем случае,

Я бы просто установил DataContext в конструкторе кода NewMessageWindow, чем прямо в xaml, с чем-то вроде:

public NewMessageWindow() { 
    InitializeComponent(); 
    var uniqueKey = System.Guid.NewGuid().ToString(); 
    DataContext = SimpleIoc.Default.GetInstance<NewMessageWindowModel>(uniqueKey); 
    Closed += (sender, args) => SimpleIoc.Default.Unregister(uniqueKey); 
} 

Таким образом, когда Window закрыт, виртуальная машина будет удалена из кеша.

Обратите внимание, что это не единственный способ сделать это, у вас есть довольно много других вариантов,

  • Вы можете сохранить связывание в XAML для DataContext и когда Window закрыт, используя Messenger класс в MVVM Light отправьте сообщение ViewModelLocator, чтобы удалить кеш.
  • Вы можете реализовать функцию Cleanup() в ViewModelLocator, чтобы удалить кеш при представлении ключа.

Выберите реализацию, которую вы предпочитаете, и пойдите с ней или используйте что-то вроде Unity или других помощников DI-контейнера, чтобы получить еще больший контроль над временем жизни объекта VM.

+0

Я поставил код в поле зрения, и он не работает, единственным решением, которое работает, является использование 'return ServiceLocator.Current.GetInstance (System.Guid.NewGuid(). ToString()) ;, но таким образом я не знаю, как избавиться от кэшированного окна. – Robert

+0

@Robert Я сделал несколько изменений в палитре кода, вы уверены, что скопировали последнюю версию? также обязательно удалите привязку xaml для 'DataContext' из' NewMessageWindow.xaml' – Viv

+0

После того, как отредактированный код будет работать. Я приму ответ. Спасибо за ваше время. – Robert

0

Этот подействующий из-за Servicelocator. которые возвращают один и тот же экземпляр объекта. где вы получаете изменения во всех общих экземплярах. Если вы хотите, чтобы у вас была конвертированная копия ViewModel. Вы coudl реализуете локатор GetNewInstance в Service.

+0

Может быть, какой-нибудь пример? – Robert

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