using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace MaterialSkin.Controls { public partial class MaterialLoader : MaterialForm { private static MaterialLoader _instance; private static Thread _loaderThread; private static ManualResetEvent _instanceReadyEvent = new ManualResetEvent(false); private readonly Dictionary _loadingProcesses; private MaterialLoader() { InitializeComponent(); RemoveMessageFilter(); _loadingProcesses = new Dictionary(); this.MaximizeBox = false; this.MinimizeBox = false; this.StartPosition = FormStartPosition.CenterScreen; } public static MaterialLoader Instance { get { if (_instance == null || _instance.IsDisposed) { _instanceReadyEvent.Reset(); _loaderThread = new Thread(() => { _instance = new MaterialLoader(); _instance.Shown += (_, _) => { _instanceReadyEvent.Set(); }; Application.Run(_instance); }); _loaderThread.SetApartmentState(ApartmentState.STA); _loaderThread.Start(); _instanceReadyEvent.WaitOne(); } return _instance; } } public void StartLoading(string title) { if (_instance == null || !_instance.Visible) { Instance.Invoke(new Action(() => { Instance.Show(); Instance.Visible= true; })); } Instance.Invoke(new Action(() => { if (_loadingProcesses.ContainsKey(title)) { return; // Prevent duplicate loading processes with the same title } var progressBar = new MaterialProgressBar { Width = Instance.ClientSize.Width - 20, Height = 20, Top = 50 + (_loadingProcesses.Count * 30), Left = 10, Style = ProgressBarStyle.Marquee, MarqueeAnimationSpeed = 30, Value = 50, BackColor = Color.White }; var label = new Label { Text = title, AutoSize = true, Top = progressBar.Top - 20, Left = progressBar.Left, BackColor = Color.White }; _loadingProcesses[title] = (progressBar, label); Instance.Controls.Add(label); Instance.Controls.Add(progressBar); Instance.Height = 50 + (_loadingProcesses.Count * 30); Instance.Refresh(); })); } public void FinishLoading(string title) { if (_instance == null) { return; } Instance.Invoke(new Action(() => { if (_loadingProcesses.TryGetValue(title, out var components)) { Instance.Controls.Remove(components.ProgressBar); Instance.Controls.Remove(components.Label); _loadingProcesses.Remove(title); RearrangeProgressBarsAndLabels(); } if (_loadingProcesses.Count == 0) { Instance.Visible= false; } })); } private void RearrangeProgressBarsAndLabels() { int index = 0; foreach (var components in _loadingProcesses.Values) { components.ProgressBar.Top = 50 + (index * 30); components.Label.Top = components.ProgressBar.Top - 20; index++; } this.Height = 50 + (_loadingProcesses.Count * 30); } } }