我正在使用SimpleMVVM Toolkit。
我有一个带有多个按钮的视图(manage_view),这些按钮将导航(设置框架的源)到新视图(manage_import_view,manage_scanners_view等)。每个视图都有自己的VM。
对于每个视图,我使用定位器将datacontext设置为VM。定位器将ServiceAgent注入VM。
问题是当我导航到其他视图时,前一个视图的状态将丢失。例如,我在Manage_Import_View上执行导入并绑定到VM上的属性。当我导航到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}"
导航就是这样
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 :(得分:0)
这对我来说似乎很笨拙。我不完全确定为什么会发生这种情况,但我可以猜测......每次请求时都会从SelectedPage
加载Uri
,这将在每次加载时设置并解析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来做这类事情,尽管如果这是一个小项目可能会有点过分。
我希望这会有所帮助。
答案 1 :(得分:0)