Form.Close()正在关闭其他窗体(对话框)

4
我有一个简单的winforms应用程序。该应用程序以MainForm开始,该窗体始终处于隐藏状态。MainForm打开另一个名为Notification的窗体(.Show),该窗体在10秒后关闭。因此,如果MainForm在Notification仍然打开时打开对话框窗体(.ShowDialog),则如果Notification达到10秒并关闭,则打开的对话框也会关闭。
通知窗体和对话框窗体都具有TopMost = True属性。
例如:
短示例: 即使我的应用程序只执行此操作,OtherDialogForm也会关闭:
public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        new Notification("Title", "Content").Show(); // closes itself after 10 seconds
        new OtherDialogForm().ShowDialog(); // being closed by form above (not wanted)
    }
}

更长的例子:MainForm.cs

public partial class MainForm : Form
{
    protected override void SetVisibleCore(bool value)
    {
        base.SetVisibleCore(false);
    }

    public MainForm() 
    {
        CreateNotification();
    }

    public void CreateNotification()
    {
        new Notification.Show();
    }

    // triggered while Notification (from above) is still open
    private async void TriggeredByHotkey()
    {
        using (OtherDialogForm dialog = new OtherDialogForm())
        {
            dialog.ShowDialog();
            // if DialogResult == ...
        }
    }
}

Notification.cs

public partial class Notification : Form
{
    Timer timer;

    public Notification()
    {
        // sets timer tick to 10 seconds,
        // then calls void with this.Close()
    }

    // not sure if I really need this, but the problem is still there without
    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            cp.ExStyle |= 8;  // Turn on WS_EX_TOPMOST
            return cp;
        }
    }
}

我真的不知道为什么对话框会随着通知一起关闭。


1
对话框需要一个所有者窗口。如果您没有使用ShowDialog(owner)重载或Owner属性提供它,则会自行查找。它将选择由同一线程拥有的活动窗口。如果您关闭或隐藏该窗口,则对话框也将消失。请注意,即使您在其构造函数中调用了ShowDialog(),它也不会是MainForm。通过使用ShowDialog(this)轻松解决此问题。 - Hans Passant
2个回答

3
您可以将通知表单隐藏而不是关闭它,因为它只是一个通知,您不需要真正关闭它,可以将其保留在后台,并在需要时显示它。 来自 msdn: https://msdn.microsoft.com/en-us/library/c7ykbedk(v=vs.110).aspx

此 ShowDialog 方法的版本未指定窗体或控件作为其所有者。调用此版本时,当前活动窗口将成为对话框框的所有者。如果要指定特定所有者,请使用此方法的其他版本。

因此,如果您正在使用 ShowDialog 并且通知表单成为其他对话框表单的父级,则在关闭通知表单时它们都将被关闭。

为了明确,这个应用程序是一个上传截图的客户端。因此,每次上传一张图片时都会出现一个带有链接的通知,但这并不是唯一需要通知的情况。例如,在笔记本电脑上,此应用程序可能运行几天,因此我不知道在后台保留这么多表单是否是一个好的做法,我也在尝试保持内存使用率更低。 - Vaza
你的修改后:现在它正常工作了!. ShowDialog(this)解决了我搜索了几天的问题。谢谢! - Vaza
尝试使用.ShowDialog(this)而不是没有参数的重载,这样做应该可以让主窗体成为对话框的父窗体。 - meJustAndrew
是的,抱歉,我在手机上写作不太快,但很高兴能帮助你! - meJustAndrew

0

如果您从通知表单触发TriggeredByHotkey方法。只有在调用者存活时,该方法才会运行。特别是如果您使用using引用对话框。

在方法结束时,由using引用的变量将调用自己的Dispose方法,这将关闭该表单。


TriggeredByHotkeyMainForm 内被触发。即使我在一个方法的 using 中调用 Notification.Show()OtherDialogForm.ShowDialog(),对话框仍然会在 10 秒后关闭。 - Vaza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接