Silverlight 4.0 使用MEF重用视图和Viewmodel&;银光
以下是我想做的: 我有一个使用导航框架和MEF的Silverlight应用程序。(像这个:) 此应用程序由一组按钮组成。单击每个按钮可加载视图及其关联的ViewModel 在这些视图中,我有一个包含项目的列表,当我单击每个项目时,它会刷新此视图中的一个子视图 我想创建一个导航系统:例如myapp.aspx#view1/2,其中2实际上是列表中单击的项目。如果我单击其中一个按钮,它将加载一个默认项并刷新所有视图,但当我单击一个项时,我不希望刷新所有视图,而只刷新视图的某些部分(我不希望创建视图和视图模型的另一个实例) 我的问题是,当我导航到此已加载的页面(例如从myapp.aspx#view1/2到myapp.aspx#view1/3)时,我希望获得对现有视图或viewmodel的引用的最佳实践(我计划在ContentLoader类的开始加载中这样做) 如果我得到viewmodel,我可以通过更改CurrentItemId属性来实现我想要的功能,该属性可以通过绑定刷新视图Silverlight 4.0 使用MEF重用视图和Viewmodel&;银光,silverlight-4.0,mef,mvvm-light,Silverlight 4.0,Mef,Mvvm Light,以下是我想做的: 我有一个使用导航框架和MEF的Silverlight应用程序。(像这个:) 此应用程序由一组按钮组成。单击每个按钮可加载视图及其关联的ViewModel 在这些视图中,我有一个包含项目的列表,当我单击每个项目时,它会刷新此视图中的一个子视图 我想创建一个导航系统:例如myapp.aspx#view1/2,其中2实际上是列表中单击的项目。如果我单击其中一个按钮,它将加载一个默认项并刷新所有视图,但当我单击一个项时,我不希望刷新所有视图,而只刷新视图的某些部分(我不希望创建视图和视
如果您有什么建议,请向davance致谢。常用的方法是使用某种形式的Messenger来执行此类操作。该项目的点击可能会触发邮件的发送,并附加该项目。所讨论的ViewModel将是订阅者,并编辑其当前设置(即:它的
ItemId
,这将触发绑定刷新)
最常见的实现通常类似于
不过,在这里您可以很容易地进行自定义,特别是因为您已经在使用MEF。只需创建一个服务来处理消息传递,并将其导入两个端点。常用的方法是使用某种形式的Messenger来执行此类操作。该项目的点击可能会触发邮件的发送,并附加该项目。所讨论的ViewModel将是订阅者,并编辑其当前设置(即:它的
ItemId
,这将触发绑定刷新)
最常见的实现通常类似于
不过,在这里您可以很容易地进行自定义,特别是因为您已经在使用MEF。只需创建一个服务来处理消息传递,并将其导入两个端点。实际上,当我单击某个项目时,我更愿意使用URI在我的应用程序中导航,但如果我使用URI,则整个视图将重新加载,而不是我想要的特定部分 有了messenger,我想我不能在视图中使用带有url的导航了吧?否则我真的不明白你向我提出了什么建议 我想采用的算法是:
- 导航(“…asp#MyView1/1”)
- MyView1是当前视图吗?
- 是的,然后我想获取当前视图的viewmodel,并将其更改为ItemId属性1
- 否,则将创建视图
- MyView1是当前视图吗?
谢谢。事实上,当我点击某个项目时,我更愿意使用URI在我的应用程序中导航,但如果我使用URI,则整个视图将重新加载,而不是我想要的特定部分 有了messenger,我想我不能在视图中使用带有url的导航了吧?否则我真的不明白你向我提出了什么建议 我想采用的算法是:
- 导航(“…asp#MyView1/1”)
- MyView1是当前视图吗?
- 是的,然后我想获取当前视图的viewmodel,并将其更改为ItemId属性1
- 否,则将创建视图
- MyView1是当前视图吗?
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();