source: stable/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ProgressView.cs @ 17500

Last change on this file since 17500 was 17500, checked in by mkommend, 8 months ago

#2973: Merged r17276, r17426, r17430, r17488 into stable.

File size: 7.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Windows.Forms;
24
25namespace HeuristicLab.MainForm.WindowsForms {
26  internal sealed partial class ProgressView : UserControl {
27    public Control TargetControl { get; }
28    public IProgress Content { get; }
29
30    public ProgressView(Control targetControl, IProgress content)
31      : base() {
32      if (targetControl == null) throw new ArgumentNullException(nameof(targetControl));
33      if (targetControl.Parent == null) throw new InvalidOperationException("A Progress can only be shown on controls that have a Parent-control. Therefore, Dialogs and Forms cannot have an associated ProgressView.");
34      if (content == null) throw new ArgumentNullException(nameof(content));
35      InitializeComponent();
36
37      this.TargetControl = targetControl;
38      this.Content = content;
39
40      if (content.ProgressState != ProgressState.Finished)
41        ShowProgress();
42      RegisterContentEvents();
43    }
44
45    protected override void Dispose(bool disposing) {
46      DeregisterContentEvents();
47
48      if (!TargetControl.IsDisposed)
49        HideProgress();
50
51      if (disposing && components != null) {
52        components.Dispose();
53      }
54      base.Dispose(disposing);
55    }
56
57    private void RegisterContentEvents() {
58      Content.ProgressStateChanged += new EventHandler(Content_ProgressStateChanged);
59      Content.MessageChanged += new EventHandler(Content_MessageChanged);
60      Content.ProgressBarModeChanged += new EventHandler(Content_ProgressBarModeChanged);
61      Content.ProgressValueChanged += new EventHandler(Content_ProgressValueChanged);
62      Content.CanBeStoppedChanged += new EventHandler(Content_CanBeStoppedChanged);
63      Content.CanBeCanceledChanged += new EventHandler(Content_CanBeCanceledChanged);
64    }
65    private void DeregisterContentEvents() {
66      Content.ProgressStateChanged -= new EventHandler(Content_ProgressStateChanged);
67      Content.MessageChanged -= new EventHandler(Content_MessageChanged);
68      Content.ProgressBarModeChanged -= new EventHandler(Content_ProgressBarModeChanged);
69      Content.ProgressValueChanged -= new EventHandler(Content_ProgressValueChanged);
70      Content.CanBeStoppedChanged -= new EventHandler(Content_CanBeStoppedChanged);
71      Content.CanBeCanceledChanged -= new EventHandler(Content_CanBeCanceledChanged);
72    }
73
74    private void Content_ProgressStateChanged(object sender, EventArgs e) {
75      UpdateProgressState();
76      UpdateButtonsState();
77    }
78
79    private void Content_MessageChanged(object sender, EventArgs e) {
80      UpdateProgressMessage();
81    }
82
83    private void Content_ProgressBarModeChanged(object sender, EventArgs e) {
84      UpdateProgressValue();
85    }
86    private void Content_ProgressValueChanged(object sender, EventArgs e) {
87      UpdateProgressValue();
88    }
89
90    private void Content_CanBeStoppedChanged(object sender, EventArgs e) {
91      UpdateButtonsState();
92    }
93    private void Content_CanBeCanceledChanged(object sender, EventArgs e) {
94      UpdateButtonsState();
95    }
96
97    private void ShowProgress() {
98      if (TargetControl.InvokeRequired) {
99        TargetControl.Invoke((Action)ShowProgress);
100        return;
101      }
102      if (Parent != null) return;
103
104      Left = (TargetControl.ClientRectangle.Width / 2) - (Width / 2);
105      Top = (TargetControl.ClientRectangle.Height / 2) - (Height / 2);
106      Anchor = AnchorStyles.None;
107
108      UpdateProgressMessage();
109      UpdateProgressValue();
110      UpdateButtonsState();
111
112      TargetControl.SuspendRepaint();
113      TargetControl.Enabled = false;
114      RegisterTargetControlEvents();
115      Parent = TargetControl.Parent;
116      BringToFront();
117      TargetControl.ResumeRepaint(true);
118      Visible = true;
119    }
120
121    private void HideProgress() {
122      if (TargetControl.InvokeRequired) {
123        TargetControl.Invoke((Action)HideProgress);
124        return;
125      }
126      if (Parent == null) return;
127
128      Visible = false;
129      TargetControl.SuspendRepaint();
130      TargetControl.Enabled = true;
131      DeregisterTargetControlEvents();
132      Parent = null;
133      TargetControl.ResumeRepaint(TargetControl.Visible);
134    }
135
136
137    private void RegisterTargetControlEvents() {
138      TargetControl.Disposed += TargetControl_Disposed;
139      TargetControl.VisibleChanged += TargetControl_VisibleChanged;
140      TargetControl.ParentChanged += TargetControl_ParentChanged;
141    }
142
143    private void DeregisterTargetControlEvents() {
144      TargetControl.Disposed -= TargetControl_Disposed;
145      TargetControl.VisibleChanged -= TargetControl_VisibleChanged;
146      TargetControl.ParentChanged -= TargetControl_ParentChanged;
147    }
148
149    private void TargetControl_Disposed(object sender, EventArgs e) {
150      Dispose();
151    }
152    private void TargetControl_VisibleChanged(object sender, EventArgs e) {
153      Visible = TargetControl.Visible;
154    }
155    private void TargetControl_ParentChanged(object sender, EventArgs e) {
156      Parent = TargetControl.Parent;
157    }
158
159    private void UpdateProgressState() {
160      if (TargetControl.InvokeRequired) {
161        TargetControl.Invoke((Action)UpdateProgressState);
162        return;
163      }
164
165      if (Content.ProgressState != ProgressState.Finished)
166        ShowProgress();
167      else
168        HideProgress();
169    }
170
171    private void UpdateProgressMessage() {
172      if (TargetControl.InvokeRequired) {
173        TargetControl.Invoke((Action)UpdateProgressMessage);
174        return;
175      }
176
177      messageLabel.Text = Content.Message;
178    }
179
180    private void UpdateProgressValue() {
181      if (InvokeRequired) {
182        Invoke((Action)UpdateProgressValue);
183        return;
184      }
185
186      switch (Content.ProgressMode) {
187        case ProgressMode.Determinate:
188          progressBar.Style = ProgressBarStyle.Continuous;
189          progressBar.Value = (int)Math.Round(progressBar.Minimum + Content.ProgressValue * (progressBar.Maximum - progressBar.Minimum));
190          break;
191        case ProgressMode.Indeterminate:
192          progressBar.Style = ProgressBarStyle.Marquee;
193          progressBar.Value = 0;
194          break;
195        default:
196          throw new NotImplementedException($"Invalid Progress Mode: {Content.ProgressMode}");
197      }
198    }
199
200    private void UpdateButtonsState() {
201      if (TargetControl.InvokeRequired) {
202        TargetControl.Invoke((Action)UpdateButtonsState);
203        return;
204      }
205
206      stopButton.Visible = Content.CanBeStopped;
207      stopButton.Enabled = Content.CanBeStopped && Content.ProgressState == ProgressState.Started;
208
209      cancelButton.Visible = Content.CanBeCanceled;
210      cancelButton.Enabled = Content.CanBeCanceled && Content.ProgressState == ProgressState.Started;
211    }
212
213    private void stopButton_Click(object sender, EventArgs e) {
214      Content.Stop();
215    }
216    private void cancelButton_Click(object sender, EventArgs e) {
217      Content.Cancel();
218    }
219  }
220}
Note: See TracBrowser for help on using the repository browser.