我有一个像这样的小popup窗口:
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; } }
它应该显示我正在加载和处理的文件的进度。 问题是在文件完成处理之前,它不呈现进度条或标签; 该窗体在主窗口的加载方法上创build,并且一旦openfiledialog完成并显示“OK”结果,就会显示该窗体。 任何帮助?
编辑:值的设置代码是相当广泛的,所以我原来select删除它,但在这里是:
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; } } } }
我建议你让文件异步打开。 也许调用BeginOpenFile或类似的,让完成功能更新进度条到100或99%,然后通过Form.Invoke或类似的关闭它。 同时在进度表里面有一个定时器,一个给定的毫秒数,例如100ms,前进10%的进度。 但不要让它达到90%以后的进展。 你不能确定需要多少时间来打开文件,你只能估计。 这就是为什么在任何应用程序进度栏往往不准确。
注意:不知道如果计时器的分辨率可以小于一秒(1000毫秒)…
如果您需要了解C#中的异步操作,一个好的资源是“通过C#的CLR”。 如果你没有这本书,可以尝试使用“执行asynchrounos IO operation .NET”的搜索功能,并查看File.BeginRead的代码示例。
别忘了Form.Invoke的东西。
Control.Invoke在拥有该控件的窗口句柄的线程上执行指定的委托,因此您可以简单地调用:
//Indicate that the process has started Invoke(ShowStatusDelegate, this.toolStripStatusLabelSpinner, true, this.toolStripStatusLabelText, "In progress...", btnGo, false);
假设该操作是通过线程或处理的。