画面開発にて、よく進捗状況を表示するためのダイアログを作成することが
よくあります。
その際、いつも参考にしているリソースです。
よく忘れるのでメモメモ。
以下のリンクの中でも特にdobonさんのページの内容が一番
わかりやすく、実用的です。(感謝)
- http://dobon.net/vb/dotnet/programing/progressdialog.html
- http://www.codeproject.com/KB/miscctrl/progressdialog.aspx
- http://www.syncfusion.com/faq/windowsforms/search/490.aspx
- http://dobon.net/vb/dotnet/programing/displayprogress.html
要は、別のスレッドでフォームをモーダルで起動するのがポイントなのですが
結構いろいろなカスタマイズを考えると作るのが難しい場合もままあり。
すご〜く適当なサンプルですが、こんな感じ。
// vim:set ts=4 sw=4 et ws is nowrap ft=cs: using System; using System.ComponentModel; using System.Data; using System.Data.Common; using System.Drawing; using System.Reflection; using System.Runtime.Remoting; using System.Threading; using System.Windows.Forms; namespace Gsf.Samples{ public class SampleLauncher{ static void Main(string[] args){ string className = typeof(Dummy).Name; if(args.Length != 0){ className = args[0]; } if(!string.IsNullOrEmpty(className)){ className = string.Format("{0}.{1}", typeof(SampleLauncher).Namespace, className); } Assembly assembly = Assembly.GetExecutingAssembly(); ObjectHandle handle = Activator.CreateInstance(assembly.FullName, className); if(handle != null){ object clazz = handle.Unwrap(); if(clazz != null){ (clazz as IExecutable).Execute(); } } } } #region "共通インターフェース定義" interface IExecutable{ void Execute(); } #endregion #region "進行状況ダイアログのサンプル" class ProgressDialogSample : IExecutable{ private class Dialog : Form{ public Dialog(){ InitializeComponent(); } protected void InitializeComponent(){ SuspendLayout(); Text = "処理中・・・・・"; Size = new Size(100, 100); TopMost = true; ControlBox = false; MaximizeBox = false; MinimizeBox = false; ShowIcon = false; ShowInTaskbar = false; ResumeLayout(); } } private class ThreadInfo{ public Form Owner{ get; set; } public Form Dialog{ get; set; } public ManualResetEvent WaitHandle{ get; set; } } private class ParentForm : Form{ public ParentForm(){ InitializeComponent(); } protected void InitializeComponent(){ SuspendLayout(); Text = "親フォーム"; Size = new Size(500, 500); Button btnShowDialog = new Button(); btnShowDialog.Text = "ダイアログ表示"; btnShowDialog.Width = 100; btnShowDialog.Dock = DockStyle.Fill; btnShowDialog.Click += (s, e) => { Enabled = false; ThreadInfo info = new ThreadInfo{Owner = this, WaitHandle = new ManualResetEvent(false)}; Thread thread = new Thread((val) => { ThreadInfo tinfo = val as ThreadInfo; Form owner = tinfo.Owner; Dialog dialog = new Dialog(); dialog.StartPosition = FormStartPosition.Manual; dialog.Left = owner.Left + (owner.Width - dialog.Width) / 2; dialog.Top = owner.Top + (owner.Height - dialog.Height) / 2; dialog.Activated += (s2, e2) => { tinfo.WaitHandle.Set(); }; tinfo.Dialog = dialog; dialog.ShowDialog(); }); thread.IsBackground = true; thread.Start(info); info.WaitHandle.WaitOne(); for(int i = 0; i < 10; i++){ string caption = string.Format("{0}%完了", ((i + 1) * 10)); info.Dialog.Invoke(new MethodInvoker(() => { info.Dialog.Text = caption; })); Thread.Sleep(1000); } info.Dialog.Invoke(new MethodInvoker(info.Dialog.Close)); Enabled = true; Activate(); }; Controls.Add(btnShowDialog); ResumeLayout(); } } [STAThread] public void Execute(){ Application.Run(new ParentForm()); } } #endregion }
実務で利用する場合は、ダイアログの管理を行なうクラスを作成し、それを経由して
ダイアログの操作を行なうようにしたりします。
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場