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的第一步(此處未顯示)。
這是否仍適用於完全依賴於用戶界面,像我的「BrowseFile」的行爲? – Alpha
@Alpha號如果你想分離一些不同的概念,然後創建自己的抽象。 – Euphoric
如果我理解正確,那麼你會直接在ViewModel中保留「BrowseFile」之類的東西,但只要這變得稍微複雜一些,就可以將這種複雜性分離出來,放到你自己的類中。這將成爲你從VM調用的東西。同樣,對於所有事情來說,管理結果和管理調用仍然會留在虛擬機內部,對吧? – Alpha