对Stylet框架进行扩展

Stylet框架适合简易开发,对于数据传输,里面只有一个简单的事件聚合器
IEventAggregator虽然可以对两个ViewModel之间相互传输数据,但是如果要返回数据,必须写两个IHandler,或者写一个Action回调,对于初级开发者来说,维护成本会增高
,但是Stylet框架提供了IWindowManager,可以打开ViewModel窗体,这样,我们可以模仿Prism框架去扩展它
1、增加代码

 // ViewModel 需实现的接口
 public interface IHaveDialogParameters
 {
     void OnDialogOpened(DialogParameters parameters);

     // 返回输出参数(返回 DialogResult)
     DialogResult OnDialogClosing();
 }

 public class DialogResult
 {
     private readonly Dictionary<string, object> _outputParameters = new Dictionary<string, object>();

     public bool? Result { get; set; }

     // 添加输出参数
     public DialogResult AddOutput(string key, object value)
     {
         _outputParameters[key] = value;
         return this;
     }

     // 获取输出参数
     public T GetOutput<T>(string key, T defaultValue = default)
     {
         return _outputParameters.TryGetValue(key, out var value) ? (T)value : defaultValue;
     }

     // 直接访问字典(备用)
     public IReadOnlyDictionary<string, object> OutputParameters => _outputParameters;
 }

 public class DialogParameters
 {
     private readonly Dictionary<string, object> _parameters = new Dictionary<string, object>();

     // 添加参数(支持链式调用)
     public DialogParameters Add(string key, object value)
     {
         _parameters[key] = value;
         return this;
     }

     // 安全获取参数(泛型 + 默认值)
     public T GetValue<T>(string key, T defaultValue = default)
     {
         return _parameters.TryGetValue(key, out var value) ? (T)value : defaultValue;
     }

     // 直接访问字典(备用)
     public IReadOnlyDictionary<string, object> Parameters => _parameters;
 }

2、增加扩展方法

 public static class WindowManagerExtensions
 {
     public static DialogResult ShowDialogEx(this IWindowManager windowManager,object viewModel,DialogParameters parameters = null)
     {
         // 1. 注入输入参数
         if (viewModel is IHaveDialogParameters dialogAware)
         {
             dialogAware.OnDialogOpened(parameters ?? new DialogParameters());
         }

         // 2. 显示对话框(原生 Stylet)
         bool? result = windowManager.ShowDialog(viewModel);

         // 3. 获取输出参数
         var dialogResult = new DialogResult { Result = result };
         if (viewModel is IHaveDialogParameters dialogAwareOut)
         {
             var output = dialogAwareOut.OnDialogClosing();
             if (output != null)
             {
                 foreach (var kvp in output.OutputParameters)
                 {
                     dialogResult.AddOutput(kvp.Key, kvp.Value);
                 }
             }
         }

         return dialogResult;
     }
 }

3、这样我们打开窗体的代码
有原来的_windowManager.ShowDialog(_shellViewModel);改为

 public ShellViewModel _shellViewModel { get; set; }

 public void OpenMsg()
 {
     // _windowManager.ShowDialog(_shellViewModel);

     var parameters = new DialogParameters();
     parameters.Add("Message", "Hello from parent!");

     var dialogResult = _windowManager.ShowDialogEx(_shellViewModel, parameters);

     if (dialogResult.Result == true)
     {
         Name = dialogResult.GetOutput<string>("Name");
         // 处理用户输入...
     }
 }

4、对打开的新窗体,我们实现接口

 public class ShellViewModel : Screen, IHaveDialogParameters
 {
     private string _message;

     public string Message
     {
         get => _message;
         set => SetAndNotify(ref _message, value);
     }

     private string _name;

     public string Name
     {
         get => _name;
         set => SetAndNotify(ref _name, value);
     }

     public ShellViewModel(IWindowManager windowManager)
     {
     }

     // 实现接口:接收参数
     public void OnDialogOpened(DialogParameters parameters)
     {
         Message = parameters.GetValue<string>("Message");
     }

     // 确定/取消命令
     public void Confirm() => RequestClose(true);

     public void Cancel() => RequestClose(false);

     public DialogResult OnDialogClosing()
     {
         return new DialogResult()
         .AddOutput("Name", Name)
         .AddOutput("Timestamp", DateTime.Now);
     }
 }
posted @ 2025-05-31 19:33  孤沉  阅读(22)  评论(0)    收藏  举报