以下是我想做的事情:
我有一个使用导航框架和MEF的Silverlight应用程序。 (像这样:http://msdn.microsoft.com/en-us/magazine/gg535672.aspx) 该应用程序由一组按钮组成。每个按钮单击加载视图及其关联的ViewModel。
在这些视图中,我有一个包含项目的列表,当我点击每个项目时,它会刷新此视图中的一种子视图。
我想创建一个导航系统:例如myapp.aspx#view1 / 2,其中2实际上是列表中单击的项目。如果我点击其中一个按钮,它将加载一个默认项目并刷新所有视图,但是当我点击一个项目时,我不想刷新所有视图但只是视图的某些部分(我不想要创建另一个视图实例和viewmodel)。
我的问题实际上是,当我导航到已经加载的页面时,我想获得对现有视图或视图模型的引用的最佳实践(例如来自myapp.aspx#view1 / 2到myapp.aspx#view1 / 3)(我打算在ContentLoader类的BeginLoad中执行此操作) 如果我获得了viewmodel,我可以通过更改例如当前的itemId属性来实现我想要的,这可以通过绑定来刷新视图。
如果你有什么建议,请多谢。
答案 0 :(得分:1)
一种常见的方法是使用某种形式的Messenger来执行此类操作。项目的单击可以触发发送消息,附加项目。有问题的ViewModel将是订阅者,并编辑其当前设置(即:它是ItemId
,这将触发绑定刷新)。
最常见的实现通常类似于Messenger service in MVVM Light。
在这里推广你自己很容易,特别是因为你已经在使用MEF了。只需创建一个服务来处理消息传递,然后将其导入两个端点。
答案 1 :(得分:0)
实际上,当我点击某个项目时,我会优先使用URI在我的应用程序中导航,但如果我使用URI,则整个视图正在重新加载而不是我想要的特定部分。
使用信使,我认为在视图中我无法使用网址导航?或者我没有弄清楚你向我提出的建议。
我想采用的算法是:
我想在那里实现这个算法:(在我的CompositionNavigationContentLoader类中,这是每个导航实例化视图的地方)
public IAsyncResult BeginLoad(Uri targetUri, Uri currentUri, AsyncCallback userCallback, object asyncState)
{
// Convert to a dummy relative Uri so we can access the host.
var relativeUri = new Uri("http://" + targetUri.OriginalString, UriKind.Absolute);
// Get the factory for the ViewModel.
var viewModelMapping = ViewModelExports.FirstOrDefault(o => o.Metadata.Key.Equals(relativeUri.Host, StringComparison.OrdinalIgnoreCase));
if (viewModelMapping == null)
throw new InvalidOperationException(
String.Format("Unable to navigate to: {0}. Could not locate the ViewModel.", targetUri.OriginalString));
// Get the factory for the View.
var viewMapping = ViewExports.FirstOrDefault(o => o.Metadata.ViewModelContract == viewModelMapping.Metadata.ViewModelContract);
if (viewMapping == null)
throw new InvalidOperationException(
String.Format("Unable to navigate to: {0}. Could not locate the View.", targetUri.OriginalString));
// Resolve both the View and the ViewModel.
var viewFactory = viewMapping.CreateExport();
var view = viewFactory.Value as Control;
var viewModelFactory = viewModelMapping.CreateExport();
var viewModel = viewModelFactory.Value as IViewModel;
// Attach ViewModel to View.
view.DataContext = viewModel;
viewModel.OnLoaded();
感谢。