Prism整合materialdesign

实现自己的对话框服务

参照prism源码IDialogService实现自己的对话框服务接口

public interface IAppDialogService
{
    void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback);

    void CloseDialog(string dialogHostName);
}

因为prism自带创建的对话框window很丑陋,且IDialogAware总带有Title属性,实际并不需要用到,故自定义个IAppDialogAware接口

public interface IAppDialogAware
{
    bool CanCloseDialog();

    /// <summary>
    /// Called when the dialog is closed.
    /// </summary>
    void OnDialogClosed();

    /// <summary>
    /// Called when the dialog is opened.
    /// </summary>
    /// <param name="parameters">The parameters passed to the dialog.</param>
    void OnDialogOpened(IDialogParameters parameters);
    
    /// <summary>
    /// Instructs the <see cref="IDialogWindow"/> to close the dialog.
    /// </summary>
    event Action<IDialogResult> RequestClose;
}

实现自己的对话框服务,集成materialdesign

public class AppDialogService:IAppDialogService
{
    private readonly IContainerExtension _containerExtension;

    public AppDialogService(IContainerExtension containerExtension)
    {
        _containerExtension = containerExtension;
    }

    public void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback)
    {
        parameters ??= new DialogParameters();

        var content = _containerExtension.Resolve<object>(name);
        var dialogContent = ParseToFrameworkElement(content);
        var viewModel = BindViewModel(dialogContent);

        viewModel.RequestClose -= callback;
        viewModel.RequestClose += callback;
        viewModel.OnDialogOpened(parameters);

        RegionManager.SetRegionManager(dialogContent, _containerExtension.Resolve<IRegionManager>());
        RegionManager.UpdateRegions();
        
        DialogHost.Show(content,"Root", null, ExtendedClosingEventHandler, closedEventHandler: ExtendedClosedEventHandler);
    }

    private void ExtendedClosingEventHandler(object sender, DialogClosingEventArgs eventArgs)
    {
        var content = eventArgs.Session?.Content;
        var dialogContent = ParseToFrameworkElement(content);
        var viewModel = BindViewModel(dialogContent);

        if (!viewModel.CanCloseDialog())
            eventArgs.Cancel(); 
    }

    private void ExtendedClosedEventHandler(object sender, DialogClosedEventArgs eventArgs)
    {
        var content = eventArgs.Session?.Content;

        var obj = ParseToFrameworkElement(content);
        var viewModel = BindViewModel(obj);

        viewModel.OnDialogClosed();

        RegionManager.SetRegionManager(obj, null);
        RegionManager.UpdateRegions();
    }

    public void CloseDialog(string dialogHostName)
    {
        DialogHost.Close(dialogHostName);
    }

    #region Private Helpers

    private FrameworkElement ParseToFrameworkElement(object content)
    {
        if (!(content is FrameworkElement obj))
            throw new NullReferenceException("A dialog's content must be a FrameworkElement");

        return obj;
    }

    private IAppDialogAware BindViewModel(FrameworkElement obj)
    {
        if (obj.DataContext is null && ViewModelLocator.GetAutoWireViewModel(obj) is null)
        {
            ViewModelLocator.SetAutoWireViewModel(obj, true);
        }

        if (!(obj.DataContext is IAppDialogAware viewModel))
            throw new NullReferenceException("A dialog's ViewModel must implement the IAppDialogAware interface");

        return viewModel;
    }

    #endregion
}

登录调用接口显示对话框,且传递参数

public class LoginViewModel:BindableBase
{
    private readonly IAppDialogService _dialogService;
    private string? _title;

    public string? Title
    {
        get => _title;
        set => SetProperty(ref _title, value);
    }

    public DelegateCommand LoginCommand { get; set; }

    public LoginViewModel(IAppDialogService dialogService)
    {
        _dialogService = dialogService;
        LoginCommand = new DelegateCommand(Login);

        Title = "this is a login view!";
    }

    private void Login()
    {
        DialogParameters parameters = new DialogParameters();
        parameters.Add("title", _title);

        _dialogService.ShowDialog("SettingDialog", parameters, (o) =>
        {
            if (o.Result == ButtonResult.OK)
            {
                Title = "登录成功";
            }
        });
    }
}

在对话框vm中OnDialogOpened接收传递参数,OnDialogClosed使用RequestClose回调结果信息和返回的参数

public class SettingDialogViewModel : BindableBase, IAppDialogAware
{
    private readonly IRegionManager _regionManager;
    
    public event Action<IDialogResult> RequestClose;

    public SettingDialogViewModel(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }

    public bool CanCloseDialog()
    {
        return true;
    }

    public void OnDialogClosed()
    {
        DialogParameters parameters = new DialogParameters();
        parameters.Add("LoginResult", true);
        RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));
    }

    public void OnDialogOpened(IDialogParameters parameters)
    {
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Prism库提供了一种称为"dispatch"的机制,用于在UI线程上自动分发事件。通过使用Prism的事件聚合器(EventAggregator)和订阅者模式,可以实现此功能。 在Prism中,发布者通过调用EventAggregator的Publish方法来引发事件。订阅者可以通过在订阅期间指定ThreadOption.UIThread来自动在UI线程上接收事件。这意味着当事件被发布时,订阅者的事件处理程序将在UI线程上执行,从而避免了在非UI线程上更新UI的问题。 以下是一个示例代码,演示了如何在Prism中使用dispatch机制: ```csharp // 发布者 public class TickerSymbolSelectedEvent : PubSubEvent<string> { } public class MainPageViewModel { private readonly IEventAggregator _eventAggregator; public MainPageViewModel(IEventAggregator eventAggregator) { _eventAggregator = eventAggregator; } public void PublishEvent(string message) { _eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Publish(message); } } // 订阅者 public class MainWindowViewModel { public MainWindowViewModel(IEventAggregator eventAggregator) { eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews, ThreadOption.UIThread); } private void ShowNews(string message) { MessageBox.Show(message); } } ``` 在上面的示例中,MainPageViewModel是一个发布者,它通过调用EventAggregator的Publish方法来引发TickerSymbolSelectedEvent事件。MainWindowViewModel是一个订阅者,它通过调用EventAggregator的Subscribe方法来订阅TickerSymbolSelectedEvent事件,并在订阅期间指定ThreadOption.UIThread,以确保ShowNews方法在UI线程上执行。 通过使用Prism的dispatch机制,可以方便地在Prism应用程序中处理UI线程上的事件分发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值