2011-08-27 53 views
4

我有一个“打开”命令,用户可以选择一个文件。当选择文件时(因此我得到的文件路径为string),我从CompositionContainer中获得DataView(具有NonSharedCreationPolicy属性)的新实例,并将其显示在特定区域中。我的DataView通过DI获得DataViewModel。现在我的问题是如何将选定的文件路径传递给新的(选择文件后创建)ViewModel?如何将参数从parentViewModel传递给ViewModel?

我的第一种方法似乎很聪明,只要我只创建一个View。但是因为我创建了多个视图(Tabs),所以下面的方法不起作用,因为我不能一次构建相同的值。

if (fileDialog.ShowDialog() == true) 
{    
    Container.ComposeExportedValue("FilePath", fileDialog.FileName); 
    IRegion contentRegion = regionManager.Regions[Regions.CONTENT]; 
    contentRegion.Add(Container.GetExportedValue<IDataView>(), null, true); 
} 

[ImportingConstructor] 
public DataViewModel(IRegionManager regionManager, 
    [Import("FilePath")] string filePath) 
{ } 

是否有任何其他方式注入/传递我的字符串参数到viewmodel?

回答

1

我认为您需要使用服务来打开文件,而不是通过MEF导出值。

如果你有一个共同的服务,所有的ViewModel使用它们,他们可以简单地导入你的服务并调用OpenFile()方法。

我有一个MVVM open source project,有一个快速的例子。请参阅模板示例here

另外检查顶部的答案here,他们有另一种实现。

+0

那是什么,我也想过,但后来我才当用户选择文件时View和ViewModel不存在的问题。它们是在用户成功选择文件时创建的。解决办法是在用户点击“打开”时创建视图及其ViewModel,如果他取消了filedialog,则销毁View和ViewModel,但听起来很尴尬。 – Basti

+0

如果您真的关注MVVM,那么您的应用程序中的每个屏幕(或部分)都会有相应的View和ViewModel。如果文件的打开在选择文件后显示一个新窗口,那么这项工作将在“父级”ViewModel中完成,并且您不需要创建(或用MEF导入)此“子级”ViewModel,直到选择该文件。 – jonathanpeppers

+0

工作实际上是在“父”视图模型中完成的,但必须显示的数据(与所选文件相关)必须以新视图显示,并且无论哪种方式,我都需要传递a)文件信息或b)由于所选文件生成的数据到新视图,否则视图不知道要显示的内容(为了更好地理解,可以观察记事本++中的打开文件过程是如何完成的。选择一个文件,然后按确定,然后会显示一个包含文件数据的新选项卡(该选项卡是我想要创建的视图) – Basti

1

我总是处理这样的事情中的ViewModel

ParentViewModel将包含OpenFileViewModel的实例,而当ParentViewModel.SelectFileCommand被执行,它会调用像OpenFileViewModel.SelectFile()

要获得所选择的文件,我经常订阅OpenFileViewModel.PropertyChanged并在FileName属性上收听更改事件,或者有时我会有一个可覆写的ProcessFile方法,我可以将一个事件连接到将在文件被选中时触发的事件。

OpenFileViewModel.SelectFile方法通常看起来像这样

private void SelectFile() 
{ 
    var dlg = new OpenFileDialog(); 
    dlg.DefaultExt = this.Extension; 
    dlg.Filter = this.Filter; 

    if (dlg.ShowDialog() == true) 
    { 
     var file = new FileInfo(dlg.FileName); 
     FileName = file.FullName; 

     if (ProcessFileDelegate != null) 
      ProcessFileDelegate() 
    } 
} 

和我ParentViewModel往往会包含的代码看起来是这样的:

public ParentViewModel() 
{ 
    this.OpenFileDialog = new OpenFileViewModel(); 
    this.OpenFileDialog.PropertyChanged += OpenFileDialog_PropertyChanged; 
    this.OpenFileDialog.ProcessFileDelegate = ProcessFile; 
}