Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Data.Views/3.3/StringConvertibleMatrixView.cs @ 4717

Last change on this file since 4717 was 4717, checked in by mkommend, 13 years ago

Corrected bug in StringConvertibleMatrixView to display all columns if the content is changed (ticket #1135).

File size: 22.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Collections.Generic;
24using System.ComponentModel;
25using System.Drawing;
26using System.Linq;
27using System.Text;
28using System.Windows.Forms;
29using HeuristicLab.Common;
30using HeuristicLab.MainForm;
31using HeuristicLab.MainForm.WindowsForms;
32
33namespace HeuristicLab.Data.Views {
34  [View("StringConvertibleMatrix View")]
35  [Content(typeof(IStringConvertibleMatrix), true)]
36  public partial class StringConvertibleMatrixView : AsynchronousContentView {
37    private int[] virtualRowIndizes;
38    private List<KeyValuePair<int, SortOrder>> sortedColumnIndizes;
39    private RowComparer rowComparer;
40
41    public new IStringConvertibleMatrix Content {
42      get { return (IStringConvertibleMatrix)base.Content; }
43      set { base.Content = value; }
44    }
45
46    public override bool ReadOnly {
47      get {
48        if ((Content != null) && Content.ReadOnly) return true;
49        return base.ReadOnly;
50      }
51      set { base.ReadOnly = value; }
52    }
53
54    private bool showRowsAndColumnsTextBox;
55    public bool ShowRowsAndColumnsTextBox {
56      get { return showRowsAndColumnsTextBox; }
57      set {
58        showRowsAndColumnsTextBox = value;
59        UpdateVisibilityOfTextBoxes();
60      }
61    }
62
63    private bool showStatisticalInformation;
64    public bool ShowStatisticalInformation {
65      get { return showStatisticalInformation; }
66      set {
67        showStatisticalInformation = value;
68        UpdateVisibilityOfStatisticalInformation();
69      }
70    }
71
72    public StringConvertibleMatrixView() {
73      InitializeComponent();
74      ShowRowsAndColumnsTextBox = true;
75      ShowStatisticalInformation = false;
76      errorProvider.SetIconAlignment(rowsTextBox, ErrorIconAlignment.MiddleLeft);
77      errorProvider.SetIconPadding(rowsTextBox, 2);
78      errorProvider.SetIconAlignment(columnsTextBox, ErrorIconAlignment.MiddleLeft);
79      errorProvider.SetIconPadding(columnsTextBox, 2);
80      sortedColumnIndizes = new List<KeyValuePair<int, SortOrder>>();
81      rowComparer = new RowComparer();
82    }
83
84    protected override void DeregisterContentEvents() {
85      Content.ItemChanged -= new EventHandler<EventArgs<int, int>>(Content_ItemChanged);
86      Content.Reset -= new EventHandler(Content_Reset);
87      Content.ColumnNamesChanged -= new EventHandler(Content_ColumnNamesChanged);
88      Content.RowNamesChanged -= new EventHandler(Content_RowNamesChanged);
89      base.DeregisterContentEvents();
90    }
91    protected override void RegisterContentEvents() {
92      base.RegisterContentEvents();
93      Content.ItemChanged += new EventHandler<EventArgs<int, int>>(Content_ItemChanged);
94      Content.Reset += new EventHandler(Content_Reset);
95      Content.ColumnNamesChanged += new EventHandler(Content_ColumnNamesChanged);
96      Content.RowNamesChanged += new EventHandler(Content_RowNamesChanged);
97    }
98
99    protected override void OnContentChanged() {
100      base.OnContentChanged();
101      if (Content == null) {
102        rowsTextBox.Text = "";
103        columnsTextBox.Text = "";
104        dataGridView.Rows.Clear();
105        dataGridView.Columns.Clear();
106        virtualRowIndizes = new int[0];
107      } else
108        UpdateData();
109    }
110
111    protected override void SetEnabledStateOfControls() {
112      base.SetEnabledStateOfControls();
113      rowsTextBox.Enabled = Content != null;
114      columnsTextBox.Enabled = Content != null;
115      dataGridView.Enabled = Content != null;
116      rowsTextBox.ReadOnly = ReadOnly;
117      columnsTextBox.ReadOnly = ReadOnly;
118      dataGridView.ReadOnly = ReadOnly;
119    }
120
121    private void UpdateData() {
122      rowsTextBox.Text = Content.Rows.ToString();
123      rowsTextBox.Enabled = true;
124      columnsTextBox.Text = Content.Columns.ToString();
125      columnsTextBox.Enabled = true;
126
127      //DataGridViews with rows but no columns are not allowed !
128      if (Content.Rows == 0 && dataGridView.RowCount != Content.Rows && !Content.ReadOnly)
129        Content.Rows = dataGridView.RowCount;
130      else
131        dataGridView.RowCount = Content.Rows;
132      if (Content.Columns == 0 && dataGridView.ColumnCount != Content.Columns && !Content.ReadOnly)
133        Content.Columns = dataGridView.ColumnCount;
134      else
135        dataGridView.ColumnCount = Content.Columns;
136      ClearSorting();
137
138      UpdateColumnHeaders();
139      UpdateRowHeaders();
140
141      dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader);
142      dataGridView.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders);
143      dataGridView.Enabled = true;
144    }
145
146    protected void UpdateColumnHeaders() {
147      HashSet<string> visibleColumnNames = new HashSet<string>(dataGridView.Columns.OfType<DataGridViewColumn>()
148          .Where(c => c.Visible && !string.IsNullOrEmpty(c.HeaderText)).Select(c => c.HeaderText));
149      if (!visibleColumnNames.Intersect(Content.ColumnNames).Any())
150        visibleColumnNames.Clear();
151
152      for (int i = 0; i < dataGridView.ColumnCount; i++) {
153        if (i < Content.ColumnNames.Count())
154          dataGridView.Columns[i].HeaderText = Content.ColumnNames.ElementAt(i);
155        else
156          dataGridView.Columns[i].HeaderText = "Column " + (i + 1);
157      }
158
159      foreach (DataGridViewColumn column in dataGridView.Columns)
160        column.Visible = visibleColumnNames.Contains(column.HeaderText) || visibleColumnNames.Count == 0;
161    }
162    protected void UpdateRowHeaders() {
163      int index = dataGridView.FirstDisplayedScrollingRowIndex;
164      if (index == -1) index = 0;
165      int updatedRows = 0;
166      int count = dataGridView.DisplayedRowCount(true);
167
168      while (updatedRows < count) {
169        if (virtualRowIndizes[index] < Content.RowNames.Count())
170          dataGridView.Rows[index].HeaderCell.Value = Content.RowNames.ElementAt(virtualRowIndizes[index]);
171        else
172          dataGridView.Rows[index].HeaderCell.Value = "Row " + (index + 1);
173        if (dataGridView.Rows[index].Visible)
174          updatedRows++;
175        index++;
176      }
177    }
178
179    private void Content_RowNamesChanged(object sender, EventArgs e) {
180      if (InvokeRequired)
181        Invoke(new EventHandler(Content_RowNamesChanged), sender, e);
182      else
183        UpdateRowHeaders();
184    }
185    private void Content_ColumnNamesChanged(object sender, EventArgs e) {
186      if (InvokeRequired)
187        Invoke(new EventHandler(Content_ColumnNamesChanged), sender, e);
188      else
189        UpdateColumnHeaders();
190    }
191    private void Content_ItemChanged(object sender, EventArgs<int, int> e) {
192      if (InvokeRequired)
193        Invoke(new EventHandler<EventArgs<int, int>>(Content_ItemChanged), sender, e);
194      else
195        dataGridView.InvalidateCell(e.Value2, e.Value);
196    }
197    private void Content_Reset(object sender, EventArgs e) {
198      if (InvokeRequired)
199        Invoke(new EventHandler(Content_Reset), sender, e);
200      else
201        UpdateData();
202    }
203
204    #region TextBox Events
205    private void rowsTextBox_Validating(object sender, CancelEventArgs e) {
206      if (ReadOnly || Locked)
207        return;
208      int i = 0;
209      if (!int.TryParse(rowsTextBox.Text, out i) || (i <= 0)) {
210        e.Cancel = true;
211        errorProvider.SetError(rowsTextBox, "Invalid Number of Rows (Valid values are positive integers larger than 0)");
212        rowsTextBox.SelectAll();
213      }
214    }
215    private void rowsTextBox_Validated(object sender, EventArgs e) {
216      if (!Content.ReadOnly) Content.Rows = int.Parse(rowsTextBox.Text);
217      errorProvider.SetError(rowsTextBox, string.Empty);
218    }
219    private void rowsTextBox_KeyDown(object sender, KeyEventArgs e) {
220      if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)
221        rowsLabel.Focus();  // set focus on label to validate data
222      if (e.KeyCode == Keys.Escape) {
223        rowsTextBox.Text = Content.Rows.ToString();
224        rowsLabel.Focus();  // set focus on label to validate data
225      }
226    }
227    private void columnsTextBox_Validating(object sender, CancelEventArgs e) {
228      if (ReadOnly || Locked)
229        return;
230      int i = 0;
231      if (!int.TryParse(columnsTextBox.Text, out i) || (i <= 0)) {
232        e.Cancel = true;
233        errorProvider.SetError(columnsTextBox, "Invalid Number of Columns (Valid values are positive integers larger than 0)");
234        columnsTextBox.SelectAll();
235      }
236    }
237    private void columnsTextBox_Validated(object sender, EventArgs e) {
238      if (!Content.ReadOnly) Content.Columns = int.Parse(columnsTextBox.Text);
239      errorProvider.SetError(columnsTextBox, string.Empty);
240    }
241    private void columnsTextBox_KeyDown(object sender, KeyEventArgs e) {
242      if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)
243        columnsLabel.Focus();  // set focus on label to validate data
244      if (e.KeyCode == Keys.Escape) {
245        columnsTextBox.Text = Content.Columns.ToString();
246        columnsLabel.Focus();  // set focus on label to validate data
247      }
248    }
249    #endregion
250
251    #region DataGridView Events
252    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
253      if (!dataGridView.ReadOnly) {
254        string errorMessage;
255        if (Content != null && !Content.Validate(e.FormattedValue.ToString(), out errorMessage)) {
256          e.Cancel = true;
257          dataGridView.Rows[e.RowIndex].ErrorText = errorMessage;
258        }
259      }
260    }
261    private void dataGridView_CellParsing(object sender, DataGridViewCellParsingEventArgs e) {
262      if (!dataGridView.ReadOnly) {
263        string value = e.Value.ToString();
264        int rowIndex = virtualRowIndizes[e.RowIndex];
265        e.ParsingApplied = Content.SetValue(value, rowIndex, e.ColumnIndex);
266        if (e.ParsingApplied) e.Value = Content.GetValue(rowIndex, e.ColumnIndex);
267      }
268    }
269    private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
270      dataGridView.Rows[e.RowIndex].ErrorText = string.Empty;
271    }
272    private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) {
273      if (Content != null && e.RowIndex < Content.Rows && e.ColumnIndex < Content.Columns) {
274        int rowIndex = virtualRowIndizes[e.RowIndex];
275        e.Value = Content.GetValue(rowIndex, e.ColumnIndex);
276      }
277    }
278
279    private void dataGridView_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e) {
280      this.UpdateRowHeaders();
281    }
282    private void dataGridView_Resize(object sender, EventArgs e) {
283      this.UpdateRowHeaders();
284    }
285
286    private void dataGridView_KeyDown(object sender, KeyEventArgs e) {
287      if (!ReadOnly && e.Control && e.KeyCode == Keys.V)
288        PasteValuesToDataGridView();
289      else if (e.Control && e.KeyCode == Keys.C)
290        CopyValuesFromDataGridView();
291    }
292
293    private void CopyValuesFromDataGridView() {
294      if (dataGridView.SelectedCells.Count == 0) return;
295      StringBuilder s = new StringBuilder();
296      int minRowIndex = dataGridView.SelectedCells[0].RowIndex;
297      int maxRowIndex = dataGridView.SelectedCells[dataGridView.SelectedCells.Count - 1].RowIndex;
298      int minColIndex = dataGridView.SelectedCells[0].ColumnIndex;
299      int maxColIndex = dataGridView.SelectedCells[dataGridView.SelectedCells.Count - 1].ColumnIndex;
300
301      if (minRowIndex > maxRowIndex) {
302        int temp = minRowIndex;
303        minRowIndex = maxRowIndex;
304        maxRowIndex = temp;
305      }
306      if (minColIndex > maxColIndex) {
307        int temp = minColIndex;
308        minColIndex = maxColIndex;
309        maxColIndex = temp;
310      }
311
312      bool addRowNames = dataGridView.AreAllCellsSelected(false) && Content.RowNames.Count() > 0;
313      bool addColumnNames = dataGridView.AreAllCellsSelected(false) && Content.ColumnNames.Count() > 0;
314
315      //add colum names
316      if (addColumnNames) {
317        if (addRowNames)
318          s.Append('\t');
319
320        DataGridViewColumn column = dataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
321        while (column != null) {
322          s.Append(column.HeaderText);
323          s.Append('\t');
324          column = dataGridView.Columns.GetNextColumn(column, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
325        }
326        s.Remove(s.Length - 1, 1); //remove last tab
327        s.Append(Environment.NewLine);
328      }
329
330      for (int i = minRowIndex; i <= maxRowIndex; i++) {
331        int rowIndex = this.virtualRowIndizes[i];
332        if (addRowNames) {
333          s.Append(Content.RowNames.ElementAt(rowIndex));
334          s.Append('\t');
335        }
336
337        DataGridViewColumn column = dataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
338        while (column != null) {
339          DataGridViewCell cell = dataGridView[column.Index, i];
340          if (cell.Selected) {
341            s.Append(Content.GetValue(rowIndex, column.Index));
342            s.Append('\t');
343          }
344
345          column = dataGridView.Columns.GetNextColumn(column, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
346        }
347        s.Remove(s.Length - 1, 1); //remove last tab
348        s.Append(Environment.NewLine);
349      }
350      Clipboard.SetText(s.ToString());
351    }
352
353    private void PasteValuesToDataGridView() {
354      string[,] values = SplitClipboardString(Clipboard.GetText());
355      int rowIndex = 0;
356      int columnIndex = 0;
357      if (dataGridView.CurrentCell != null) {
358        rowIndex = dataGridView.CurrentCell.RowIndex;
359        columnIndex = dataGridView.CurrentCell.ColumnIndex;
360      }
361
362      for (int row = 0; row < values.GetLength(1); row++) {
363        if (row + rowIndex >= Content.Rows)
364          Content.Rows = Content.Rows + 1;
365        for (int col = 0; col < values.GetLength(0); col++) {
366          if (col + columnIndex >= Content.Columns)
367            Content.Columns = Content.Columns + 1;
368          Content.SetValue(values[col, row], row + rowIndex, col + columnIndex);
369        }
370      }
371      ClearSorting();
372    }
373    private string[,] SplitClipboardString(string clipboardText) {
374      clipboardText = clipboardText.Remove(clipboardText.Length - Environment.NewLine.Length);  //remove last newline constant
375      string[,] values = null;
376      string[] lines = clipboardText.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
377      string[] cells;
378      for (int i = 0; i < lines.Length; i++) {
379        cells = lines[i].Split('\t');
380        if (values == null)
381          values = new string[cells.Length, lines.Length];
382        for (int j = 0; j < cells.Length; j++)
383          values[j, i] = string.IsNullOrEmpty(cells[j]) ? string.Empty : cells[j];
384      }
385      return values;
386    }
387
388    private void dataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
389      if (Content != null) {
390        if (e.Button == MouseButtons.Left && Content.SortableView) {
391          bool addToSortedIndizes = (Control.ModifierKeys & Keys.Control) == Keys.Control;
392          SortOrder newSortOrder = SortOrder.Ascending;
393          if (sortedColumnIndizes.Any(x => x.Key == e.ColumnIndex)) {
394            SortOrder oldSortOrder = sortedColumnIndizes.Where(x => x.Key == e.ColumnIndex).First().Value;
395            int enumLength = Enum.GetValues(typeof(SortOrder)).Length;
396            newSortOrder = oldSortOrder = (SortOrder)Enum.Parse(typeof(SortOrder), ((((int)oldSortOrder) + 1) % enumLength).ToString());
397          }
398
399          if (!addToSortedIndizes)
400            sortedColumnIndizes.Clear();
401
402          if (sortedColumnIndizes.Any(x => x.Key == e.ColumnIndex)) {
403            int sortedIndex = sortedColumnIndizes.FindIndex(x => x.Key == e.ColumnIndex);
404            if (newSortOrder != SortOrder.None)
405              sortedColumnIndizes[sortedIndex] = new KeyValuePair<int, SortOrder>(e.ColumnIndex, newSortOrder);
406            else
407              sortedColumnIndizes.RemoveAt(sortedIndex);
408          } else
409            if (newSortOrder != SortOrder.None)
410              sortedColumnIndizes.Add(new KeyValuePair<int, SortOrder>(e.ColumnIndex, newSortOrder));
411          Sort();
412        }
413      }
414    }
415
416    protected virtual void ClearSorting() {
417      virtualRowIndizes = Enumerable.Range(0, Content.Rows).ToArray();
418      sortedColumnIndizes.Clear();
419      UpdateSortGlyph();
420    }
421
422    private void Sort() {
423      virtualRowIndizes = Sort(sortedColumnIndizes);
424      UpdateSortGlyph();
425      UpdateRowHeaders();
426      dataGridView.Invalidate();
427    }
428    protected virtual int[] Sort(IEnumerable<KeyValuePair<int, SortOrder>> sortedColumns) {
429      int[] newSortedIndex = Enumerable.Range(0, Content.Rows).ToArray();
430      if (sortedColumns.Count() != 0) {
431        rowComparer.SortedIndizes = sortedColumns;
432        rowComparer.Matrix = Content;
433        Array.Sort(newSortedIndex, rowComparer);
434      }
435      return newSortedIndex;
436    }
437    private void UpdateSortGlyph() {
438      foreach (DataGridViewColumn col in this.dataGridView.Columns)
439        col.HeaderCell.SortGlyphDirection = SortOrder.None;
440      foreach (KeyValuePair<int, SortOrder> p in sortedColumnIndizes)
441        this.dataGridView.Columns[p.Key].HeaderCell.SortGlyphDirection = p.Value;
442    }
443    #endregion
444
445    public class RowComparer : IComparer<int> {
446      public RowComparer() {
447      }
448
449      private List<KeyValuePair<int, SortOrder>> sortedIndizes;
450      public IEnumerable<KeyValuePair<int, SortOrder>> SortedIndizes {
451        get { return this.sortedIndizes; }
452        set { sortedIndizes = new List<KeyValuePair<int, SortOrder>>(value); }
453      }
454      private IStringConvertibleMatrix matrix;
455      public IStringConvertibleMatrix Matrix {
456        get { return this.matrix; }
457        set { this.matrix = value; }
458      }
459
460      public int Compare(int x, int y) {
461        int result = 0;
462        double double1, double2;
463        DateTime dateTime1, dateTime2;
464        TimeSpan timeSpan1, timeSpan2;
465        string string1, string2;
466
467        if (matrix == null)
468          throw new InvalidOperationException("Could not sort IStringConvertibleMatrix if the matrix member is null.");
469        if (sortedIndizes == null)
470          return 0;
471
472        foreach (KeyValuePair<int, SortOrder> pair in sortedIndizes.Where(p => p.Value != SortOrder.None)) {
473          string1 = matrix.GetValue(x, pair.Key);
474          string2 = matrix.GetValue(y, pair.Key);
475          if (double.TryParse(string1, out double1) && double.TryParse(string2, out double2))
476            result = double1.CompareTo(double2);
477          else if (DateTime.TryParse(string1, out dateTime1) && DateTime.TryParse(string2, out dateTime2))
478            result = dateTime1.CompareTo(dateTime2);
479          else if (TimeSpan.TryParse(string1, out timeSpan1) && TimeSpan.TryParse(string2, out timeSpan2))
480            result = timeSpan1.CompareTo(timeSpan2);
481          else {
482            if (string1 != null)
483              result = string1.CompareTo(string2);
484            else if (string2 != null)
485              result = string2.CompareTo(string1) * -1;
486          }
487          if (pair.Value == SortOrder.Descending)
488            result *= -1;
489          if (result != 0)
490            return result;
491        }
492        return result;
493      }
494    }
495
496    private void dataGridView_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) {
497      if (Content == null) return;
498      if (e.Button == MouseButtons.Right && Content.ColumnNames.Count() != 0)
499        contextMenu.Show(MousePosition);
500    }
501    private void ShowHideColumns_Click(object sender, EventArgs e) {
502      new ColumnsVisibilityDialog(this.dataGridView.Columns.Cast<DataGridViewColumn>()).ShowDialog();
503    }
504
505    private void UpdateVisibilityOfTextBoxes() {
506      rowsTextBox.Visible = columnsTextBox.Visible = showRowsAndColumnsTextBox;
507      rowsLabel.Visible = columnsLabel.Visible = showRowsAndColumnsTextBox;
508      UpdateDataGridViewSizeAndLocation();
509    }
510
511    private void UpdateVisibilityOfStatisticalInformation() {
512      statusStrip.Visible = showStatisticalInformation;
513      UpdateDataGridViewSizeAndLocation();
514    }
515
516    private void UpdateDataGridViewSizeAndLocation() {
517      int headerSize = columnsTextBox.Location.Y + columnsTextBox.Size.Height +
518       columnsTextBox.Margin.Bottom + dataGridView.Margin.Top;
519
520      int offset = showRowsAndColumnsTextBox ? headerSize : 0;
521      dataGridView.Location = new Point(0, offset);
522
523      int statusStripHeight = showStatisticalInformation ? statusStrip.Height : 0;
524      dataGridView.Size = new Size(Size.Width, Size.Height - offset - statusStripHeight);
525    }
526
527    private void dataGridView_SelectionChanged(object sender, EventArgs e) {
528      toolStripStatusLabel.Text = string.Empty;
529      if (dataGridView.SelectedCells.Count > 1) {
530        List<double> selectedValues = new List<double>();
531        foreach (DataGridViewCell cell in dataGridView.SelectedCells) {
532          double value;
533          if (!double.TryParse(cell.Value.ToString(), out value)) return;
534          selectedValues.Add(value);
535        }
536        if (selectedValues.Count > 1) {
537          StringBuilder labelText = new StringBuilder();
538          labelText.Append("Average: " + selectedValues.Average() + "    ");
539          labelText.Append("StdDev: " + selectedValues.StandardDeviation() + "    ");
540          labelText.Append("Sum: " + selectedValues.Sum() + "    ");
541          labelText.Append("Count: " + selectedValues.Count + "    ");
542          toolStripStatusLabel.Text = labelText.ToString();
543        }
544      }
545    }
546  }
547}
Note: See TracBrowser for help on using the repository browser.