首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在打开模态对话框时处理锁定应用程序?

如何在打开模态对话框时处理锁定应用程序?
EN

Stack Overflow用户
提问于 2019-06-13 14:32:43
回答 1查看 482关注 0票数 1

我正在处理的应用程序使用模态对话框。我目前正在实现会话超时,它会在一定数量的非活动分钟后自动锁定屏幕,但我遇到了一个问题,如果用户打开了一个模态对话框,它将显示在会话锁定屏幕的顶部。

在WPF .Net应用程序中,用于识别和强制关闭任何模态对话框(使用取消操作)的一般逻辑是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-13 20:13:51

有一些复杂的模态对话框,这是最好的说明通过实例。下面的处理程序在单击时生成一个新的Window,然后是一个MessageBox,等待第二个,然后关闭两者。注意,我们希望MainWindow保持开放。

代码语言:javascript
运行
复制
public partial class MainWindow : Window
{
    const int timeout = 1000;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var win = new Window { Content = new Label { Content = "Not a modal Window" } };

        using (new Timer(OnTimerElapsed, win, timeout, Timeout.Infinite))
        {
            win.Show();

            MessageBox.Show($"Open windows: {Application.Current.Windows.Count}", "Just a sec...");
        }
    }

    private void OnTimerElapsed(object state)
    {
        Application.Current.Dispatcher.BeginInvoke(
            DispatcherPriority.Background,
            new Action(() =>
            {
                ((Window)state).Close();
            }));
    }
}

这个例子的主要内容是非模态窗口和MessageBox都是关闭的。然而,如果我们仔细看看OnTimerElapsed,我们会发现只有非模态窗口才被告知关闭。考虑到这是调用MessageBox.Show时(最后一次)活动的窗口,它也是MessageBox的所有者,因此关闭它也会关闭MessageBox。

我们可以用MessageBox.Show(...);替换行new OpenFileDialog().ShowDialog();,得到类似的结果。

这就把我们带到了最高层。如果我们想关闭一个从主窗口实例化的MessageBox,我们如何在不同时关闭这两个窗口的情况下做到这一点呢?一种选择是创建一个虚拟所有者窗口,这个窗口从未显示过,只是充当一个调用Close的引用。

代码语言:javascript
运行
复制
public partial class MainWindow : Window
{
    const int timeout = 1000;
    private Window _modalOwner;

    public MainWindow()
    {
        InitializeComponent();
        InitializeModalOwner();
    }

    private void InitializeModalOwner()
    {
        _modalOwner = new Window
        {
            AllowsTransparency = true,
            ShowInTaskbar = false,
            WindowStyle = WindowStyle.None,
            Background = Brushes.Transparent
        };
        _modalOwner.Show();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        using (new Timer(OnTimerElapsed, null, timeout, Timeout.Infinite))
        {
            MessageBox.Show(_modalOwner, $"Open windows: {Application.Current.Windows.Count}", "Just a sec...");
        }
    }

    private void OnTimerElapsed(object state)
    {
        Application.Current.Dispatcher.BeginInvoke(
            DispatcherPriority.Background,
            new Action(() =>
            {
                var mainWindow = Application.Current.MainWindow;
                foreach (Window win in Application.Current.Windows)
                    if(win != mainWindow)
                        win.Close();
                InitializeModalOwner();
            }));
    }
}

在这里,我们迭代当前WindowCollection中的所有窗口,并关闭它们,只要它们不是应用程序的主窗口。在此之后,_modalOwner也将被关闭,这使它变得毫无用处--一旦Window实例关闭,您就不能调用它。这也是再次初始化它的地方。

new OpenFileDialog().ShowDialog(_modalOwner);也是如此。调用Window的任何ShowDialog实例都将自动添加到Application.Current.Windows集合中。

资源

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56582844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档