【问题标题】:Prism IDialogService Show Non-Modal Dialog acts as ModalPrism IDialogService 显示非模态对话框充当模态
【发布时间】:2020-10-19 01:43:28
【问题描述】:

在 WPF Prism 7.2 中,我遵循了IDialogService instructions shown here

我有一个 PlotsDialogPanel UserControl 和一个 ContentControl,如下所示:

<UserControl x:Class="PlotModule.Dialogs.Views.PlotsDialogPanel"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True"
             xmlns:local="clr-namespace:PlotModule.Dialogs.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <prism:Dialog.WindowStyle>
        <Style TargetType="Window">
            <Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
            <Setter Property="ResizeMode" Value="CanResizeWithGrip"/>
            <Setter Property="ShowInTaskbar" Value="True"/>
        </Style>
    </prism:Dialog.WindowStyle>

    <Grid>
        <ContentControl prism:RegionManager.RegionName="PlotsDialogDisplayRegion" />
    </Grid>
</UserControl>

在我的PlotModule RegisterTypes 方法中我注册了对话框:

public void RegisterTypes(IContainerRegistry containerRegistry)
{
   containerRegistry.RegisterDialog<PlotsDialogPanel, PlotsDialogPanelViewModel>();
}

但是当对话框显示在事件处理程序中时,它充当模式,它始终位于父级的最顶层。

private void MainMenuEventHandler(string inParameter)
{
   _DialogService.Show("PlotsDialogPanel", new DialogParameters(), r => {});
}

我在这里看不到我做错了什么,关于为什么对话框表现得像模态的任何想法?其他一切都按预期工作,对话框显示并关闭,IDialogAware::OnDialogOpenedOnDialogClosed 按预期运行。

【问题讨论】:

    标签: c# wpf prism


    【解决方案1】:

    它实际上不是模态的,只是最顶部的窗口。使用ShowDialog 方法显示一个模态对话框,它不仅会是最顶层的窗口,还会禁用用户与其所有者窗口的任何交互,直到被关闭。

    对话框位于另一个窗口之上的原因是它有一个所有者窗口分配给它的Owner 属性。默认情况下,Prism 将始终将应用程序中的第一个 活动 窗口分配为对话框的所有者,除非您在对话框主机上明确设置了 not null 的所有者窗口。

    请参阅 GitHub 上 DialogService 的实现以供参考。此行设置对话框的Owner

    if (window.Owner == null)
       window.Owner = Application.Current.Windows.OfType<Window>().FirstOrDefault(x => x.IsActive);
    

    由于这是实现DialogService 的方式,因此您必须创建自己的对话服务并更改行为。例如,您可以提供重载以不设置所有者。实现原始的IDialogService 接口以提供对默认实现的兼容性。

    public interface ICustomDialogService : IDialogService
    {
       public void ShowOrphan(string name, IDialogParameters parameters, Action<IDialogResult> callback);
    }
    

    创建一个派生自ICustomDialogService 的类型CustomDialogService,并从GitHub 复制original implementation。通过将参数传递给ConfigureDialogWindowProperties 方法来调整原始方法,以确定是否设置Owner 并采取相应措施。

    public class CustomDialogService : ICustomDialogService
    {
       // ...other public members.
    
       public void ShowOrphan(string name, IDialogParameters parameters, Action<IDialogResult> callback)
       {
          // Appended a new parameter "isOrphan"
          ShowDialogInternal(name, parameters, callback, false, true);
       }
    
       // ...other private members.
    
       // Appended a new parameter "isOrphan"
       void ConfigureDialogWindowProperties(IDialogWindow window, FrameworkElement dialogContent, IDialogAware viewModel, bool isOrphan)
       {
          // ...other code.
    
          if (isOrphan)
             return;
    
          if (window.Owner == null)
             window.Owner = System.Windows.Application.Current.Windows.OfType<Window>().FirstOrDefault(x => x.IsActive);
       }
    }
    

    向您的界面和原始界面注册自定义对话服务,以便您可以同时使用两者。

    containerRegistry.RegisterSingleton <CustomDialogService>();
    containerRegistry.Register<IDialogService, CustomDialogService>();
    containerRegistry.Register<ICustomDialogService, CustomDialogService>();
    

    可能还有其他变通方法,例如创建忽略Owner 属性的自定义对话主机窗口或其他技巧,但我认为创建自定义对话服务是这里最干净的方法。

    【讨论】:

    • 这是一个很好的解释,谢谢!我已按照建议实施,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多