2016-06-14 183 views
0

我給我的WPF和MVVM的第一個步驟,使用Prism隔離命令邏輯。到目前爲止,這麼好,但有一種我無法實現的特定設計方法。WPF MVVM:從視圖模型

在我的UI,我打開文件的方法有兩種。有一個可以單擊的瀏覽按鈕,將出現一個打開文件對話框,提示輸入文件並將其打開。您也可以將文件拖放到用戶界面頂部,然後將其打開。

爲了分離瀏覽邏輯,I爲它創建的命令。出現第一個代碼異味,我需要一個ICommand接口沒有公開的結果。

public class BrowseFileCommand: ICommand 
{ 
    public string ExecutionResult { get; private set; } 

    public bool CanExecute(object parameter) => true; 

    public void Execute(object parameter) 
    { 
     var openFileDialog = new OpenFileDialog() 
     { 
      Multiselect = false, 
      Filter = "Event log files (*.evtx)|*.evtx" 
     }; 

     ExecutionResult = openFileDialog.ShowDialog() == true ? openFileDialog.FileName : null; 
    } 

    public event EventHandler CanExecuteChanged; 
} 

然後,在我的ViewModel類,我可以調用它像這樣:

public class MainWindowViewModel: BindableBase 
{ 
    public DelegateCommand BrowseFileCommand { get; set; } 

    public MainWindowViewModel() 
    { 
     BrowseFileCommand = new DelegateCommand(BrowseAndOpenFile,() => _browseFileCommand.CanExecute(null)); 
     // ... 
    } 

    private BrowseFileCommand _browseFileCommand = new BrowseFileCommand(); 

    private void BrowseAndOpenFile() 
    { 
     _browseFileCommand.Execute(null); 
     var fileName = _browseFileCommand.ExecutionResult; 
     if (!string.IsNullOrWhiteSpace(fileName)) 
      OpenFile(fileName); 
    } 

    // ... 
} 

這裏有一些其他的代碼味道:

  • 我需要到結束我的命令另一個命令後會讀取它的值執行
  • 我無法正常鏈接起來CanExecuteChanged事件(我不需要,但似乎我應該如果我窩命令)
  • 帶有null參數調用CanExecute()(據我所看到的,這是「共同」,但仍然是一個代碼味道對我來說),因爲ICommand需要它
  • 不帶參數調用CanExecute() ,因爲棱鏡的DelegateCommand允許它。
  • 我仍然留在視圖模型,這正是我想避免在首位的「膠合」的邏輯。

有沒有一種很好的方法可以將邏輯完全隔離到Command/class?

請注意以下設計限制:

  • 這些動作屬於UI邏輯:BrowseCommand嚴格與正在使用
  • 某些命令可能之間共享的UI技術動作。注意OpenFile是瀏覽文件後的第二步,但是Drop的第一步(此處未顯示)。

回答

0

ICommand主要用於綁定到UI。它並不意味着被用於行爲分離,並從正常代碼中調用。這就是爲什麼你得到你的代碼味道。

取而代之,使用正常的語言功能(方法,繼承,組合等)來分隔關注點,並使用命令向UI展示綁定的特定操作。

+0

這是否仍適用於完全依賴於用戶界面,像我的「BrowseFile」的行爲? – Alpha

+0

@Alpha號如果你想分離一些不同的概念,然後創建自己的抽象。 – Euphoric

+0

如果我理解正確,那麼你會直接在ViewModel中保留「BrowseFile」之類的東西,但只要這變得稍微複雜一些,就可以將這種複雜性分離出來,放到你自己的類中。這將成爲你從VM調用的東西。同樣,對於所有事情來說,管理結果和管理調用仍然會留在虛擬機內部,對吧? – Alpha