开发者

C# thread and ShowDialog problem

ProgressForm Class:

public partial class ProgressForm : Form
    {
        public int prc = 0, sz;
        MainForm mf;

        public ProgressForm(MainForm MF)
        {
            InitializeComponent();
            mf = MF;
            sz = 0;
        }

        public ProgressForm(int mx)
        {
            InitializeComponent();
            sz = mx;
        }

        public void SetMax(int mx)
        {
            sz = mx;
        }

        public void StartProgress()
        {
            timer1.Enabled = true;
        }

        public void IncProgress(int prg)
        {
            prc += prg;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            double pos = (double)prc / (double)sz * 100;
            progressBar.Value = (int)pos;
        }

        private void ProgressForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            timer1.Enabled = false;
        }

        private void cancelBtn_Click(object sender, EventArgs e)
        {
            mf.isCanceled = true;
            this.Close();
        }

        private void ProgressForm_Shown(object sender, EventArgs e)
        {
            progressBar.Value = 0;
            StartProgress();
        }

    }

MainForm class:

void DeleteFiles()
            {
                int x = 0;
                int cnt = resultList.Count;
                isCanceled = false;

                DeleteThreadHandler("beginprogress");
                try
                {
                    DeleteThreadHandler("begindelete");
                    for (int j = 0; j < cnt; j++)
                    {
                        if (resultList[x].isChecked)
                        {
                            DeleteThreadHandler("progress");
                            DeleteFile(resultList[x].name, deleteForm.isDeletePermanently);
                            if (File.Exists(resultList[x].name))
                            {
                                DeleteErrorHandler(resultList[x].name);
                                isError = true;
                            }
                            else
                                resultList.RemoveAt(x);
                        }
                        else
                            ++x;

                        if (isCanceled)
                            break;
                    }
                }
                finally
                {
                    validity(true);
                    DeleteThreadHandler("enddelete");
                }
            }

            void DeleteErrorHandler(string val)
            {
                Action action = null;

                action = () =>
                {
                    errorReportForm.AddError(val);
                };

                this.BeginInvoke(action);
            }

            void DeleteThreadHandler(String title)
            {
                Action action = null;
                if (title == "beginprogress")
                {
                    action = () =>
                    {

                    };
                }
                else
                if (title == "begindelete")
                {
                    action = () =>
                    {
                        olvVirtual.BeginUpdate();
                    };
                }
                else
                    if (title == "enddelete")
                    {
                        action = () =>
                        {
                            olvVirtual.VirtualListSize = resultList.Count;
                            olvVirtual.EndUpdate();
                            RefreshStatus();
                            progressForm.Close();
                            if (isError)
                                errorReportForm.ShowDialog();
                        };
                    }
                if (title == "progress")
     开发者_开发知识库           {
                    action = () =>
                    {
                        progressForm.IncProgress(1);
                    };
                }

                this.BeginInvoke(action);
            }    


    private void DeleteBtn_Click(object sender, EventArgs e)
        {
            int checkedcount = GetCheckedCount();
            if (checkedcount == 0)
            {
                MessageBox.Show("Please mark at least a file first");
                return;
            }
            DialogResult dr = new DialogResult();
            if (deleteForm == null)
                deleteForm = new DeleteForm();
            dr = deleteForm.ShowDialog();
            if (dr == DialogResult.OK)
            {
                //if (progressForm == null)
                progressForm = new ProgressForm(this);
                progressForm.Text = "Deleting...";
                progressForm.SetMax(checkedcount);

                if (errorReportForm == null)
                    errorReportForm = new ErrorReportForm();
                errorReportForm.ClearMemo();
                isError = false;

                Thread t = new Thread(DeleteFiles);
                t.Start();
                progressForm.ShowDialog();
            }
        }

In progressForm, there are a progress bar & timer which update the progress every 500 ms. The problem is I still can access the main form, I also try BeginInvoke but neither works Anyone know what is wrong ?

Thanks

EDITED: I've found source of this mess, it's DeleteFile which use Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile. After replaced it with unmanaged code it works fine.


Try

 progressForm.ShowDialog(this);  // assuming this is the main form


It's hard to say exactly what the cause of this is, but you'll have a better chance of discovering the cause with a bit of debugging.

I would try the following;

  • When you run ShowDialog on DeleteForm, does this behave as a modal dialog for DeleteForm or can you still click the underlying form while DeleteForm is visible? If not, does it when you run ShowDialog(this)?

  • Call progressForm.ShowDialog(this) and set a couple of breakpoints (1) at the beginning of DeleteFiles and (2) at line progressForm.IncProgress(1); When the breakpoints are hit, use the immediate window to check progressForm.Owner and progressForm.Modal

Also, what are you passing a reference to the current object into progress form for? Is there anything in the constructor of ProgressForm that could cause these issues?

Another thing to note on Modal Dialogs from MSDN is the use of the Close button. The following comes from; http://msdn.microsoft.com/en-us/library/w61zzfwe.aspx

When a form is displayed as a modal dialog box, clicking the Close button (the button with an X at the upper-right corner of the form) causes the form to be hidden and the DialogResult property to be set to DialogResult.Cancel. Unlike modeless forms, the Close method is not called by the .NET Framework when the user clicks the close form button of a dialog box or sets the value of the DialogResult property. Instead the form is hidden and can be shown again without creating a new instance of the dialog box. Because a form displayed as a dialog box is hidden instead of closed, you must call the Dispose method of the form when the form is no longer needed by your application.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜