2014-02-05 3 views
1

Я использую SimpleMVVM Toolkit.Сохранять состояние пользовательского интерфейса от ViewModel при переключении просмотров

У меня есть вид (manage_view) с несколькими кнопками, которые будут перемещаться (установить источник кадра) в новые виды (manage_import_view, manage_scanners_view и т. Д.). У каждого представления есть собственная виртуальная машина.

Для каждого из видов я устанавливаю datacontext для виртуальной машины с помощью локатора. Локатор вводит ServiceAgent в виртуальную машину.

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

Я понимаю, что происходит, но я не уверен, как его решить. Как сохранить состояние просмотров при переключении между ними?

С нетерпением ждем ваших соображений по этому вопросу.

(Я искал Switching between views according to state, но это не совсем то, что мне нужно.)

Редактировать

Мой локатор

public ImportViewModel ImportViewModel 
{ 
    get 
    { 
     IIntegrationServiceAgent sa = new IntegrationServiceAgent(); 
     return new ImportViewModel(sa); 
    } 
} 

В XAML мой взгляд, я установить DataContext

DataContext="{Binding Source={StaticResource Locator}, Path=ImportViewModel}"  

Навигация is lik e so

private void Navigate(string pageName) 
{ 
    Uri pageUri = new Uri("/Views/" + pageName + ".xaml", UriKind.Relative); 
    this.SelectedPage = pageUri; 
    this.SelectedPageName = pageName; 
} 

У меня есть обратный вызов завершения после того, как импорт завершен. Это устанавливает реквизиты, привязанные к моему представлению, - - это те, которые сбрасываются после переключения представлений.

private void ImportCompleted(IntegrationResult intresult, Exception error) 
    { 
     if (error == null) 
     { 
      _errorCount = intresult.Errors.Count; 
      ErrorList = intresult.Errors; 

      ResultMessage = intresult.Message; 
      ErrorMessage = (errorList.Count == 1 ? "1 error" : errorList.Count.ToString() + " errors"); 
      Notify(ImportCompleteNotice, null); // Tell the view we're done     
      ShowErrorDialog(importType); 
     } 
     else 
      NotifyError(error.Message, error); 

     IsImportBusy = false; 
    } 
+0

Есть ли 'TabControl', который содержит ваши представления? – MoonKnight

+0

Killercam, я решил не использовать TabControl, но функциональность, на которую я нацелилась, такая же. – ceebreenk

+0

Существует стандартный способ хранения содержимого элемента управления вкладкой в ​​памяти, но трудно понять, почему компоненты пользовательского интерфейса не хранятся в том случае, если вы описываете ... Можете ли вы прояснить изображение и некоторый код/​​XAML? – MoonKnight

ответ

0

Это кажется неуклюжим для меня. Я не совсем уверен, почему это происходит, но я могу догадаться ... Вы загружаете SelectedPage с Uri s каждый раз, когда они запрашиваются, это будет устанавливать и анализировать XAML каждый раз, когда они будут загружены, что повлияет на ваши привязки. Вот что я хотел бы сделать:

Сначала на Запуск приложения, загружать все соображения в список просмотра

private Dictionary<string, Uri> viewUriDict; 
private List<string> viewNameList = new List<string>() 
{ 
    "ViewA", 
    "ViewB" 
}; 

// The main View Model constructor. 
public MainViewModel() 
{ 
    viewUriDict = new Dictionary<string, Uri>(); 
    foreach (string s in viewNameList) 
     viewUriDict.Add(s, new Uri("/Views/" + s + ".xaml", UriKind.Relative); 
    this.SelectedPageName = viewNameList[0]; 
} 

private string selectedPageName; 
public string SelectedPageName 
{ 
    get { return this.selectedPageName; } 
    set 
    { 
     if (this.selectedPageName == value) 
      return; 
     this.selectedPageName = value; 
     this.SelectedPage = this.viewUriDict[this.selectedPageName]; 
     OnPropertyChanged("SelectedPageName"); // For INotifyPropertyChanged. 
    } 
} 

private Uri selectedPage; 
private Uri selectedPageName 
{ 
    get { return this.selectedPage; } 
    set 
    { 
     if (this.selectedPage == value) 
      return; 
     this.selectedPage = value; 
     OnPropertyChanged("SelectedPage"); // For INotifyPropertyChanged. 
    } 
} 

Так что теперь Uri список кэшируется в главном окне/приложении. Навигация затем стать

private void Navigate(string pageName) 
{ 
    this.SelectedPageName = pageName; 
} 

или просто установив this.SelectedPageName = "PageX".

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

private IIntegrationServiceAgent sa; 
public ImportViewModel ImportViewModel 
{ 
    get 
    { 
     if (sa == null) 
      sa = new IntegrationServiceAgent(); 
     return new ImportViewModel(sa); 
    } 
} 

Это может решить проблему, или не может. В любом случае, я надеюсь, что это имеет какую-то ценность.Если бы я был вами, я бы посмотрел на использование Prism, чтобы сделать этот тип вещей, хотя это может быть излишним, если это небольшой проект.

Надеюсь, это поможет.

+0

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

0

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

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