0

我有以下 WaitScreen 类,在执行后台进程时显示“请稍候...”消息:

public class WaitScreen
    {
        // Fields
        private object lockObject = new object();
        private string message = "Please Wait...";
        private Form waitScreen;

        // Methods
        public void Close()
        {
            lock (this.lockObject)
            {
                if (this.IsShowing)
                {
                    try
                    {
                        this.waitScreen.Invoke(new MethodInvoker(this.CloseWindow));
                    }
                    catch (NullReferenceException)
                    {
                    }
                    this.waitScreen = null;
                }
            }
        }

        private void CloseWindow()
        {
            this.waitScreen.Dispose();
        }

        public void Show(string message)
        {
            if (this.IsShowing)
            {
                this.Close();
            }
            if (!string.IsNullOrEmpty(message))
            {
                this.message = message;
            }
            using (ManualResetEvent event2 = new ManualResetEvent(false))
            {
                Thread thread = new Thread(new ParameterizedThreadStart(this.ThreadStart));
                thread.SetApartmentState(ApartmentState.STA);
                thread.Start(event2);
                event2.WaitOne();
            }
        }

        private void ThreadStart(object parameter)
        {
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
            ManualResetEvent event2 = (ManualResetEvent)parameter;
            Application.EnableVisualStyles();
            this.waitScreen = new Form();
            this.waitScreen.Tag = event2;
            this.waitScreen.ShowIcon = false;
            this.waitScreen.ShowInTaskbar = false;
            this.waitScreen.AutoSize = true;
            this.waitScreen.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            this.waitScreen.BackColor = SystemColors.Window;
            this.waitScreen.ControlBox = false;
            this.waitScreen.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            this.waitScreen.StartPosition = FormStartPosition.CenterScreen;
            this.waitScreen.Cursor = Cursors.WaitCursor;
            this.waitScreen.Text = "";
            this.waitScreen.FormClosing += new FormClosingEventHandler(this.WaitScreenClosing);
            this.waitScreen.Shown += new EventHandler(this.WaitScreenShown);
            Label label = new Label();
            label.Text = this.message;
            label.AutoSize = true;
            label.Padding = new Padding(20, 40, 20, 30);
            this.waitScreen.Controls.Add(label);
            Application.Run(this.waitScreen);
            Application.ExitThread();
        }

        private void WaitScreenClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
            }
        }

        private void WaitScreenShown(object sender, EventArgs e)
        {
            Form form = (Form)sender;
            form.Shown -= new EventHandler(this.WaitScreenShown);
            ManualResetEvent tag = (ManualResetEvent)form.Tag;
            form.Tag = null;
            tag.Set();
        }

        // Properties
        public bool IsShowing
        {
            get
            {
                return (this.waitScreen != null);
            }
        }
    }

我使用它的方式是:

waitScreen = new WaitScreen();
waitScreen.Show("Please wait...");

我有一个 MainForm,在一个主窗体内我有一个按钮,单击时我会显示一个对话框,加载时将从 Backgroundworker 中的数据库获取一些数据。在运行 backgroundworker 之前,我展示了我的WaitScreen

它工作得很好,但是当显示WaitScreen时,如果我点击后面的对话框,那么WaitScreen就消失了。所以我想阻止,所以在工作人员完成之前我不能点击后面的对话框,然后我关闭我的WaitScreen

关于如何做到这一点的任何线索?

非常感谢。

4

1 回答 1

1

我认为你过于复杂了。您想要的是一个用户无法关闭的模态对话框窗口,该窗口将在给定任务完成时关闭。

您可以创建一个标准类,该类派生自Form并实现可以传递任务或回调的构造函数或属性。

WaitScreen以下是代码在您的表单中的样子:

public partial class WaitScreen : Form
{
    public Action Worker { get; set; }

    public WaitScreen(Action worker)
    {
        InitializeComponent();

        if (worker == null)
            throw new ArgumentNullException();

        Worker = worker;
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        Task.Factory.StartNew(Worker).ContinueWith(t => { this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());
    }
}

WaitScreen以下是您的代码在此表单的使用者中的样子:

private void someButton_Click(object sender, EventArgs e)
{
    using (var waitScreen = new WaitScreen(SomeWorker))
        waitScreen.ShowDialog(this);
}

private void SomeWorker()
{
    // Load stuff from the database and store it in local variables.
    // Remember, this is running on a background thread and not the UI thread, don't touch controls.
}

您可能希望在 WaitScreen 中使用 FormBorderStyle.None 以便用户无法关闭它。然后任务完成,WaitScreen 将自行关闭,调用者将在调用后继续执行代码ShowDialog()ShowDialog()阻塞调用线程。

于 2013-10-03T14:55:51.113 回答