【问题标题】:How can I pass parameters from a parentViewModel to my ViewModel?如何将参数从 parentViewModel 传递到我的 ViewModel?
【发布时间】:2011-11-05 06:27:08
【问题描述】:

我有一个“打开”命令,用户可以在其中选择一个文件。 When the file is chosen (and therefore I have got the filepath as a string) I get a new instance of my DataView (with the NonShared and CreationPolicy attributes) out of the CompositionContainer and display it在特定区域。我的DataView 通过 DI 得到它的DataViewModel。现在我的问题是如何将选定的文件路径传递给 NEW(在选择文件后创建)ViewModel?

我的第一种方法似乎很聪明,只要我只创建了一个 View 就可以工作。但是由于我创建了多个视图(选项卡),因此以下方法不起作用,因为我不能多次组合相同的值。

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)
{ }

还有其他方法可以将我的字符串参数注入/传递给视图模型吗?

【问题讨论】:

    标签: c# .net mvvm prism mef


    【解决方案1】:

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

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

    我有一个MVVM open source project,它有一个这样做的简单示例。请参阅模板示例here

    还可以查看最佳答案here,他们有另一个实现。

    【讨论】:

    • 我也是这么想的,但是后来发现用户选择文件时View和ViewModel都不存在的问题。它们是在用户成功选择文件时创建的。一种解决方案是在用户单击“打开”时创建 View 及其 ViewModel,如果他取消文件对话框,则销毁 View 和 ViewModel,但这听起来很尴尬。
    • 如果您真正关注 MVVM,那么您的应用程序中的每个屏幕(或部分)都会有一个合适的 View 和 ViewModel。如果在选择文件后打开文件会显示一个新窗口,那么这项工作将在“父”视图模型中完成,并且在选择文件之前您不需要创建(或使用 MEF 导入)这个“子”视图模型.
    • 这项工作实际上是在“父”视图模型中完成的,但是必须显示的数据(与所选文件相关)必须显示在新视图中,无论哪种方式我都需要通过)文件的信息或b)由于选择的文件而生成的数据到新视图,否则视图不知道要显示什么(为了更好地理解可以看一下fe Notepadd ++中打开文件的过程是怎样的完成。您按打开,选择一个文件,然后按确定,然后显示一个带有文件数据的新选项卡(该选项卡是我要创建的视图)。
    • 您的新标签只需要公开一个字符串属性,父 ViewModel 将使用文件名设置该属性。
    • 通过 Views Datacontext 注入依赖项(这是我必须做的,因为我的 View 创建了 ViewModel -> View.DataContext.MyStringProperty = myString;)听起来很尴尬。当我找到一个“干净”的解决方案时,我将使用该解决方案编辑我的问题。不过还是谢谢
    【解决方案2】:

    我总是在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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-12
      • 2014-09-15
      • 2022-06-10
      • 2013-09-21
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 2022-11-25
      相关资源
      最近更新 更多