1

我有一个像这样的小弹出窗口:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SQLProcWriter
{
    public partial class Progress : Form
    {
        public Progress()
        {
            InitializeComponent();
            progressBar1.Minimum = 0;
            progressBar1.Maximum = 100;
        }
    }
}

namespace SQLProcWriter
{
    partial class Progress
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Progress));
            this.progressBar1 = new System.Windows.Forms.ProgressBar();
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // progressBar1
            // 
            resources.ApplyResources(this.progressBar1, "progressBar1");
            this.progressBar1.Name = "progressBar1";
            this.progressBar1.UseWaitCursor = true;
            // 
            // label1
            // 
            resources.ApplyResources(this.label1, "label1");
            this.label1.Name = "label1";
            this.label1.UseWaitCursor = true;
            // 
            // Progress
            // 
            resources.ApplyResources(this, "$this");
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Controls.Add(this.label1);
            this.Controls.Add(this.progressBar1);
            this.Name = "Progress";
            this.UseWaitCursor = true;
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        public System.Windows.Forms.ProgressBar progressBar1;
        public System.Windows.Forms.Label label1;
    }
}

它应该显示我正在加载和处理的文件的进度。问题是在文件完成处理之前它不会呈现进度条或标签;该表单是在主窗口的加载方法上创建的,一旦 openfiledialog 完成并显示“OK”结果,就会显示该表单。有什么帮助吗?

编辑:设置值的代码非常广泛,所以我最初选择删除它,但这里是:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace SQLProcWriter
{
    public partial class Form1 : Form
    {
        private string Script { get; set; }
        private List<string> File { get; set; }
        private List<string> CreateStatements { get; set; }
        private List<Table> Tables { get; set; }
        private List<string> FieldBuffer { get; set; }
        private Progress progressWindow;
        private int progressValue;

        private const string CREATE_SEPARATOR = "create table ";
        private string[] FIELD_SEPARATOR = new string[] { @"\t", @" "};

        public Form1()
        {
            InitializeComponent();
            File = new List<string>();
            FieldBuffer = new List<string>();
            Tables = new List<Table>();
            CreateStatements = new List<string>();
            progressValue = 0;
            progressWindow = new Progress();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            About about = new About();
            about.Show();
        }

        private void Convert()
        {
            bool adding = false, nullableBuffer = false;
            string buffer = "", buffer2 = "";
            Table currentTable = new Table();
            currentTable.ForeignKeys = new List<ForeignKey>();
            currentTable.Columns = new List<Column>();
            int startIndex = 0, endIndex = 0;
            int linesDone = 0;
            int totalLines = File.Count();
            progressWindow.label1.Text = "Reading \'Create\' Statements";

            foreach (string s in File)
            {
                //Extract column names
                if (adding)
                {
                    if (s.Contains(@")") && s.Length == 1)
                    {
                        adding = false;
                        Tables.Add(currentTable);
                        currentTable = new Table();
                        currentTable.Columns = new List<Column>();
                        currentTable.ForeignKeys = new List<ForeignKey>();
                        currentTable.TableName = "";
                        currentTable.PrimaryKey = new PrimaryKey();
                    }
                    else
                    {
                        if (s != @"(")
                        {
                            if (s != "\t")
                            {
                                if (s.Contains("constraint"))
                                {
                                    //Constraint rules here
                                    if (s.Contains("primary key clustered"))
                                    {
                                        startIndex = s.IndexOf("(");
                                        startIndex++;
                                        endIndex = s.IndexOf(")");

                                        buffer = s.Substring(startIndex, (endIndex - startIndex));


                                        currentTable.PrimaryKey = new PrimaryKey(buffer, "int");
                                    }
                                    else if (s.Contains("foreign key"))
                                    {
                                        startIndex = s.IndexOf("(");
                                        startIndex++;
                                        endIndex = s.IndexOf(")");
                                        buffer = s.Substring(startIndex, (endIndex - startIndex));

                                        startIndex = s.IndexOf("references ");
                                        startIndex += 11;
                                        endIndex = s.Length;

                                        buffer2 = s.Substring(startIndex, (endIndex - startIndex));
                                        endIndex = buffer2.IndexOf(String.Format("({0}", buffer));
                                        buffer2 = buffer2.Substring(0, endIndex);


                                        currentTable.ForeignKeys.Add(new ForeignKey(buffer, buffer2));
                                    }
                                }
                                else
                                {
                                    //Regular table field
                                    buffer = s.Substring(s.IndexOf("\t") + 1, s.IndexOf(" "));

                                    startIndex = s.IndexOf(" ");
                                    startIndex++;
                                    endIndex = s.IndexOf(",");

                                    buffer2 = s.Substring(startIndex, (endIndex - startIndex));

                                    if (buffer2.Contains("not null"))
                                    {
                                        nullableBuffer = false;
                                        buffer2 = buffer2.Remove(buffer2.IndexOf(" "));
                                    }
                                    else
                                        nullableBuffer = true;

                                    currentTable.Columns.Add(new Column(buffer, buffer2, nullableBuffer));
                                }
                            }
                        }
                    }
                }

                //Extract Table Names
                if (s.Contains(CREATE_SEPARATOR))
                {
                    adding = true;
                    buffer = s;
                    currentTable.TableName = buffer.Remove(0, 13);
                }

                linesDone++;
                progressValue = (((linesDone / totalLines) * 100) / 4) + 25;
                progressWindow.progressBar1.Value = progressValue;
            }

            ProcessForeignKeys();
            ProcessPrimaryKeys();
            Tables = Utils.TrimEverything(Tables);
        }

        private void ProcessForeignKeys()
        {
            int keysDone = 0;
            int totalKeys = 0;
            progressWindow.label1.Text = "Processing Foreign Keys";

            foreach (Table t in Tables)
                foreach (ForeignKey fk in t.ForeignKeys)
                    totalKeys++;

            foreach (Table t in Tables)
                foreach (ForeignKey fk in t.ForeignKeys)
                {
                    for (int i = 0; i < t.Columns.Count; i++)
                        if (t.Columns[i].Name.Contains(fk.Name))
                        {
                            fk.DataType = t.Columns[i].DataType;
                            t.Columns.RemoveAt(i);
                        }

                    keysDone++;
                    progressValue = (((keysDone / totalKeys) * 100) / 4) + 50;
                }
        }

        private void ProcessPrimaryKeys()
        {
            int primaryKeys = 0;
            int totalKeys = Tables.Count();
            progressWindow.label1.Text = "Processing Primary Keys";

            foreach (Table t in Tables)
            {
                for (int i = 0; i < t.Columns.Count; i++)
                {
                    if (t.Columns[i].DataType.Contains("identity"))
                    {
                        t.Columns.RemoveAt(i);
                        primaryKeys++;
                        progressValue = (((primaryKeys / totalKeys) * 100) / 4) + 75;
                        progressWindow.progressBar1.Value = progressValue;
                    }
                }
            }

            progressWindow.label1.Text = "Done!";
            progressWindow.Hide();
            progressWindow.progressBar1.Value = 0;
            progressWindow.label1.Text = "";
            progressValue = 0;
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OutputTextBox.Text = "";
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Environment.SpecialFolder.MyDocuments.ToString();
            ofd.Filter = "SQL Script File (.sql)|*.sql";
            ofd.Multiselect = false;
            ofd.Title = "Select an SQL Script File";

            Stream fileStream = null;

            int currentLine = 0;
            int totalLines = 0;

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                progressWindow.Show();

                if ((fileStream = ofd.OpenFile()) != null)
                {
                    TextReader tr = new StreamReader(fileStream);
                    string line;
                    totalLines = System.IO.File.ReadLines(ofd.FileName).Count();

                    while ((line = tr.ReadLine()) != null)
                    {
                        File.Add(line);
                        OutputTextBox.Text += line + "\r\n";

                        currentLine++;
                        progressValue = (int)(((currentLine / totalLines) * 100) / 4);
                        progressWindow.progressBar1.Value = progressValue;
                    }

                    Convert();
                }
            }
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            Script = string.Empty;
            OutputTextBox.Text = string.Empty;
        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void ConvertButton_Click(object sender, EventArgs e)
        {
            List<string> Output = new List<string>();
            progressWindow.Show();
            progressWindow.label1.Text = "Creating SQL";
            int total = Tables.Count();
            int done = 0;

            Output.Add(String.Format("--Auto-generated code (c) {0} Logic & Design", System.DateTime.Now.Year));

            foreach (Table t in Tables)
            {
                //Add a comment
                Output.Add(String.Format("--Procs for {0}", t.TableName));

                #region List
                Output.Add(String.Format("create proc {0}_List", t.TableName));
                Output.Add("as");
                Output.Add(String.Format("\tselect * from {0}", t.TableName));
                #endregion

                #region Get
                Output.Add(String.Format("create proc {0}_Get", t.TableName));
                Output.Add(String.Format("@{0} {1}", t.PrimaryKey.Name, t.PrimaryKey.DataType));
                Output.Add("as");
                Output.Add(String.Format("\tif"));
                #endregion

                #region Create
                #endregion

                #region Update
                #endregion

                #region Delete
                #endregion

                done++;
                progressValue = (done / total) * 100;
                progressWindow.progressBar1.Value = progressValue;
            }
        }
    }
}
4

2 回答 2

1

我建议你让文件异步打开。也许调用 BeginOpenFile 或类似的方法,让完成功能将进度条更新为 100% 或 99%,然后通过 Form.Invoke 或类似方法关闭它。同时,在进度表中有一个计时器,一旦给定的毫秒数(例如 100 毫秒),进度就会提高 10%。但不要让它在达到 90% 后设定进度。您无法确定打开文件需要多长时间,您只能估计。这就是为什么任何应用程序中的进度条往往不准确的原因。

注意:不确定计时器分辨率是否可以小于一秒(1000 毫秒)...

如果您需要了解 C# 中的异步操作,一个很好的资源是“CLR via C#”。如果您没有那本书,请尝试使用谷歌搜索“执行 asynchrounos IO 操作 .NET”并查看 File.BeginRead 的代码示例。

并且不要忘记 Form.Invoke 的事情。

于 2012-10-10T15:44:34.990 回答
0

Control.Invoke 在拥有控件窗口句柄的线程上执行指定的委托,因此您可以简单地调用:

//Indicate that the process has started
        Invoke(ShowStatusDelegate, this.toolStripStatusLabelSpinner, true, this.toolStripStatusLabelText, "In progress...", btnGo, false);

假设动作是线程化的或处理的。

于 2012-10-10T15:27:38.963 回答