2011-08-27 57 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; 
}