首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关闭OpenFileDialog/SaveFileDialog

关闭OpenFileDialog/SaveFileDialog
EN

Stack Overflow用户
提问于 2012-08-23 19:37:18
回答 4查看 10.9K关注 0票数 6

我们有一个要求关闭子窗体作为自动注销的一部分。我们可以通过从定时器线程迭代Application.OpenForms来关闭子窗体。由于OpenFileDialog未列出,我们无法使用Application.OpenForms关闭OpenFileDialog/SaveFileDialog。

如何关闭OpenFileDialog和CloseFileDialog?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-08-23 20:58:54

这将需要pinvoke,对话框不是窗体,而是本机Windows对话框。基本方法是枚举所有顶层窗口,并检查它们的类名是否为"#32770",这是Windows拥有的所有对话框的类名。并通过发送WM_CLOSE消息强制关闭对话框。

向您的项目添加一个新类,并粘贴如下所示的代码。当注销计时器超时时调用DialogCloser.Execute()。然后关闭表单。该代码适用于MessageBox、OpenFormDialog、FolderBrowserDialog、PrintDialog、ColorDialog、FontDialog、PageSetupDialog和SaveFileDialog。

代码语言:javascript
复制
using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

static class DialogCloser {
    public static void Execute() {
        // Enumerate windows to find dialogs
        EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);
        EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero);
        GC.KeepAlive(callback);
    }

    private static bool checkWindow(IntPtr hWnd, IntPtr lp) {
        // Checks if <hWnd> is a Windows dialog
        StringBuilder sb = new StringBuilder(260);
        GetClassName(hWnd, sb, sb.Capacity);
        if (sb.ToString() == "#32770") {
            // Close it by sending WM_CLOSE to the window
            SendMessage(hWnd, 0x0010, IntPtr.Zero, IntPtr.Zero);
        }
        return true;
    }

    // P/Invoke declarations
    private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
    [DllImport("user32.dll")]
    private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
    [DllImport("kernel32.dll")]
    private static extern int GetCurrentThreadId();
    [DllImport("user32.dll")]
    private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}
票数 15
EN

Stack Overflow用户

发布于 2012-08-23 19:42:19

我不会在一个线程中关闭所有的子窗体,而是引发一个每个子窗体都可以/必须订阅的事件。在提升表单时,您可以决定现在要做什么。清理一些东西,持久化状态,在你的表单范围内向服务器发送一条消息你可以访问something对话框,然后尝试关闭它。

票数 1
EN

Stack Overflow用户

发布于 2012-08-23 21:03:18

这里的解决方法是示例:

您应该定义完全透明的window ex。“传送器”;

每次需要显示对话框时,都需要显示TRANSP并将TRANSP作为参数传递给ShowDialog方法。

当应用程序关闭时-调用TRANSP窗口的Close()方法。子对话框将关闭。

代码语言:javascript
复制
    public partial class MainWindow : Window
{
    OpenFileDialog dlg;
    TranspWnd transpWnd;

    public MainWindow()
    {
        InitializeComponent();

        Timer t = new Timer();
        t.Interval = 2500;
        t.Elapsed += new ElapsedEventHandler(t_Elapsed);
        t.Start();
    }

    void t_Elapsed(object sender, ElapsedEventArgs e)
    {
        Dispatcher.BeginInvoke(new Action(() =>
        {
            transpWnd.Close();
        }), null);
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        transpWnd = new TranspWnd();
        transpWnd.Visibility = System.Windows.Visibility.Hidden; //doesn't works right
        transpWnd.Show();

        dlg = new OpenFileDialog();
        dlg.ShowDialog(transpWnd);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12090691

复制
相关文章

相似问题

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