MVVM模式下Material Design WPF对话框返回值实现方法问询
Material Design DialogHost 返回输入值实现方案
需求背景
使用Material Design for WPF的DialogHost实现输入对话框,要求点击保存时返回用户输入的Name或自定义对象;同时因Prism对话框无法满足在内容控件中央显示的需求,选择Material Design DialogHost,且希望保持对话框ViewModel独立,避免主ViewModel因绑定过多对话框VM导致代码臃肿。
实现步骤
1. 修改对话框ViewModel,传递返回值
在对话框VM的OnSave方法中,使用DialogHost.Close的重载版本,将需要返回的值作为第二个参数传入:
public class TakeSomeInputDialogViewModel : ViewModelBase { private string _name; public string Name { get => _name; set { SetProperty(ref _name, value); SaveCommand.RaiseCanExecuteChanged(); } } public bool IsNameInvalid => !CanSave(); public DelegateCommand SaveCommand { get; } public TakeSomeInputDialogViewModel() { SaveCommand = new DelegateCommand(OnSave, CanSave); } private void OnSave() { // 直接传递Name作为返回值,也可构造自定义对象传入 DialogHost.Close("RootDialog", Name); // 若需返回自定义对象,示例: // var resultModel = new YourCustomModel { UserName = Name }; // DialogHost.Close("RootDialog", resultModel); } private bool CanSave() { return !string.IsNullOrEmpty(Name); } }
2. 主ViewModel中接收返回值
在打开对话框的方法中,直接接收DialogHost.Show的返回结果,还可通过关闭事件处理程序做额外校验:
private async void OnOpenDialog() { var view = new TakeInputDialogView(); // 为对话框绑定独立VM,避免与主VM耦合 view.DataContext = new TakeSomeInputDialogViewModel(); var result = await DialogHost.Show(view, "RootDialog", ClosingEventHandler); // 处理返回结果 if (result != null) { if (result is string inputName) { // 在这里使用返回的Name值 // 例如:this.UserName = inputName; } // 若返回自定义对象,示例: // else if (result is YourCustomModel model) // { // // 处理自定义对象逻辑 // } } } // 可选:关闭事件拦截,用于最后校验或阻止关闭 private void ClosingEventHandler(object sender, DialogClosingEventArgs eventArgs) { // 示例:若返回值为空,阻止对话框关闭 if (eventArgs.Parameter is string name && string.IsNullOrEmpty(name)) { eventArgs.Cancel(); // 可添加输入无效的提示逻辑 } }
3. 保持对话框VM独立的注意事项
- 对话框VM自行管理输入校验、命令逻辑,主VM仅负责打开对话框和接收结果,避免两者耦合
- 每个对话框对应独立的VM,主VM无需绑定多个对话框VM,减少代码臃肿
- 可封装DialogHost的打开逻辑为扩展方法,进一步简化主VM代码(例如:
await DialogHost.ShowDialog<TakeSomeInputDialogViewModel>("RootDialog"))
内容的提问来源于stack exchange,提问作者Miraziz
相关产品推荐
相关产品推荐

