Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3324 was 3324, checked in by mkommend, 14 years ago

fixed small bug in StringConvertibleMatrixView (ticket #968)

File size: 12.6 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.ComponentModel;
24using System.Collections.Generic;
25using System.Drawing;
26using System.Linq;
27using System.Windows.Forms;
28using HeuristicLab.Common;
29using HeuristicLab.MainForm;
30using HeuristicLab.MainForm.WindowsForms;
31
32namespace HeuristicLab.Data.Views {
33  [View("StringConvertibleMatrix View")]
34  [Content(typeof(IStringConvertibleMatrix), true)]
35  public partial class StringConvertibleMatrixView : AsynchronousContentView {
36    public new IStringConvertibleMatrix Content {
37      get { return (IStringConvertibleMatrix)base.Content; }
38      set { base.Content = value; }
39    }
40
41    private int[] virtualRowIndizes;
42    private List<KeyValuePair<int, SortOrder>> sortedColumnIndizes;
43    RowComparer rowComparer;
44
45    public StringConvertibleMatrixView() {
46      InitializeComponent();
47      Caption = "StringConvertibleMatrix View";
48      errorProvider.SetIconAlignment(rowsTextBox, ErrorIconAlignment.MiddleLeft);
49      errorProvider.SetIconPadding(rowsTextBox, 2);
50      errorProvider.SetIconAlignment(columnsTextBox, ErrorIconAlignment.MiddleLeft);
51      errorProvider.SetIconPadding(columnsTextBox, 2);
52      sortedColumnIndizes = new List<KeyValuePair<int, SortOrder>>();
53      rowComparer = new RowComparer();
54    }
55    public StringConvertibleMatrixView(IStringConvertibleMatrix content)
56      : this() {
57      Content = content;
58    }
59
60    protected override void DeregisterContentEvents() {
61      Content.ItemChanged -= new EventHandler<EventArgs<int, int>>(Content_ItemChanged);
62      Content.Reset -= new EventHandler(Content_Reset);
63      Content.ColumnNamesChanged -= new EventHandler(Content_ColumnNamesChanged);
64      Content.RowNamesChanged -= new EventHandler(Content_RowNamesChanged);
65      base.DeregisterContentEvents();
66    }
67
68
69    protected override void RegisterContentEvents() {
70      base.RegisterContentEvents();
71      Content.ItemChanged += new EventHandler<EventArgs<int, int>>(Content_ItemChanged);
72      Content.Reset += new EventHandler(Content_Reset);
73      Content.ColumnNamesChanged += new EventHandler(Content_ColumnNamesChanged);
74      Content.RowNamesChanged += new EventHandler(Content_RowNamesChanged);
75    }
76
77
78
79    protected override void OnContentChanged() {
80      base.OnContentChanged();
81      sortedColumnIndizes.Clear();
82      if (Content == null) {
83        Caption = "StringConvertibleMatrix View";
84        rowsTextBox.Text = "";
85        rowsTextBox.Enabled = false;
86        columnsTextBox.Text = "";
87        columnsTextBox.Enabled = false;
88        dataGridView.Rows.Clear();
89        dataGridView.Columns.Clear();
90        dataGridView.Enabled = false;
91        virtualRowIndizes = new int[0];
92      } else {
93        Caption = "StringConvertibleMatrix (" + Content.GetType().Name + ")";
94        UpdateData();
95      }
96    }
97
98    private void UpdateData() {
99      rowsTextBox.Text = Content.Rows.ToString();
100      rowsTextBox.Enabled = true;
101      columnsTextBox.Text = Content.Columns.ToString();
102      columnsTextBox.Enabled = true;
103      virtualRowIndizes = Enumerable.Range(0, Content.Rows).ToArray();
104      dataGridView.EndEdit();
105      dataGridView.RowCount = 0;
106      dataGridView.ColumnCount = 0;
107      if ((Content.Rows > 0) && (Content.Columns > 0)) {
108        dataGridView.RowCount = Content.Rows;
109        dataGridView.ColumnCount = Content.Columns;
110        UpdateRowHeaders();
111        UpdateColumnHeaders();
112      }
113      dataGridView.ReadOnly = Content.ReadOnlyView;
114      dataGridView.Enabled = true;
115    }
116
117    private void UpdateColumnHeaders() {
118      for (int i = 0; i < Content.Columns; i++) {
119        if (Content.ColumnNames.Count() != 0)
120          dataGridView.Columns[i].HeaderText = Content.ColumnNames.ElementAt(i);
121        else
122          dataGridView.Columns[i].HeaderText = "Column " + i;
123      }
124      dataGridView.Invalidate();
125    }
126
127    private void UpdateRowHeaders() {
128      for (int i = dataGridView.FirstDisplayedScrollingRowIndex; i < dataGridView.FirstDisplayedScrollingRowIndex + dataGridView.DisplayedRowCount(true); i++) {
129        if (Content.RowNames.Count() != 0)
130          dataGridView.Rows[i].HeaderCell.Value = Content.RowNames.ElementAt(i);
131        else
132          dataGridView.Rows[i].HeaderCell.Value = i.ToString();
133      }
134      dataGridView.Invalidate();
135    }
136
137    private void Content_RowNamesChanged(object sender, EventArgs e) {
138      UpdateColumnHeaders();
139    }
140
141    private void Content_ColumnNamesChanged(object sender, EventArgs e) {
142      UpdateRowHeaders();
143    }
144
145    private void Content_ItemChanged(object sender, EventArgs<int, int> e) {
146      if (InvokeRequired)
147        Invoke(new EventHandler<EventArgs<int, int>>(Content_ItemChanged), sender, e);
148      else {
149        dataGridView.InvalidateCell(e.Value, e.Value2);
150      }
151    }
152    private void Content_Reset(object sender, EventArgs e) {
153      if (InvokeRequired)
154        Invoke(new EventHandler(Content_Reset), sender, e);
155      else
156        UpdateData();
157    }
158
159    #region TextBox Events
160    private void rowsTextBox_Validating(object sender, CancelEventArgs e) {
161      int i = 0;
162      if (!int.TryParse(rowsTextBox.Text, out i) || (i < 0)) {
163        e.Cancel = true;
164        errorProvider.SetError(rowsTextBox, "Invalid Number of Rows (Valid Values: Positive Integers Larger or Equal to 0)");
165        rowsTextBox.SelectAll();
166      }
167    }
168    private void rowsTextBox_Validated(object sender, EventArgs e) {
169      Content.Rows = int.Parse(rowsTextBox.Text);
170      errorProvider.SetError(rowsTextBox, string.Empty);
171    }
172    private void rowsTextBox_KeyDown(object sender, KeyEventArgs e) {
173      if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)
174        rowsLabel.Focus();  // set focus on label to validate data
175      if (e.KeyCode == Keys.Escape) {
176        rowsTextBox.Text = Content.Rows.ToString();
177        rowsLabel.Focus();  // set focus on label to validate data
178      }
179    }
180    private void columnsTextBox_Validating(object sender, CancelEventArgs e) {
181      int i = 0;
182      if (!int.TryParse(columnsTextBox.Text, out i) || (i < 0)) {
183        e.Cancel = true;
184        errorProvider.SetError(columnsTextBox, "Invalid Number of Columns (Valid Values: Positive Integers Larger or Equal to 0)");
185        columnsTextBox.SelectAll();
186      }
187    }
188    private void columnsTextBox_Validated(object sender, EventArgs e) {
189      Content.Columns = int.Parse(columnsTextBox.Text);
190      errorProvider.SetError(columnsTextBox, string.Empty);
191    }
192    private void columnsTextBox_KeyDown(object sender, KeyEventArgs e) {
193      if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)
194        columnsLabel.Focus();  // set focus on label to validate data
195      if (e.KeyCode == Keys.Escape) {
196        columnsTextBox.Text = Content.Columns.ToString();
197        columnsLabel.Focus();  // set focus on label to validate data
198      }
199    }
200    #endregion
201
202    #region DataGridView Events
203    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
204      string errorMessage;
205      if (!Content.Validate(e.FormattedValue.ToString(), out errorMessage)) {
206        e.Cancel = true;
207        dataGridView.Rows[e.RowIndex].ErrorText = errorMessage;
208      }
209    }
210    private void dataGridView_CellParsing(object sender, DataGridViewCellParsingEventArgs e) {
211      string value = e.Value.ToString();
212      int rowIndex = virtualRowIndizes[e.RowIndex];
213      e.ParsingApplied = Content.SetValue(value, rowIndex, e.ColumnIndex);
214      if (e.ParsingApplied) e.Value = Content.GetValue(rowIndex, e.ColumnIndex);
215    }
216    private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
217      dataGridView.Rows[e.RowIndex].ErrorText = string.Empty;
218    }
219    private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) {
220      int rowIndex = virtualRowIndizes[e.RowIndex];
221      e.Value = Content.GetValue(rowIndex, e.ColumnIndex);
222    }
223
224    private void dataGridView_Scroll(object sender, ScrollEventArgs e) {
225      UpdateRowHeaders();
226    }
227
228    private void dataGridView_Resize(object sender, EventArgs e) {
229      UpdateRowHeaders();
230    }
231
232    private void dataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
233      if (Content != null) {
234        if (e.Button == MouseButtons.Left && Content.SortableView) {
235          bool addToSortedIndizes = (Control.ModifierKeys & Keys.Control) == Keys.Control;
236          SortOrder newSortOrder = SortOrder.Ascending;
237          if (sortedColumnIndizes.Any(x => x.Key == e.ColumnIndex)) {
238            SortOrder oldSortOrder = sortedColumnIndizes.Where(x => x.Key == e.ColumnIndex).First().Value;
239            int enumLength = Enum.GetValues(typeof(SortOrder)).Length;
240            newSortOrder = oldSortOrder = (SortOrder)Enum.Parse(typeof(SortOrder), ((((int)oldSortOrder) + 1) % enumLength).ToString());
241          }
242
243          if (!addToSortedIndizes)
244            sortedColumnIndizes.Clear();
245
246          if (sortedColumnIndizes.Any(x => x.Key == e.ColumnIndex)) {
247            int sortedIndex = sortedColumnIndizes.FindIndex(x => x.Key == e.ColumnIndex);
248            if (newSortOrder != SortOrder.None)
249              sortedColumnIndizes[sortedIndex] = new KeyValuePair<int, SortOrder>(e.ColumnIndex, newSortOrder);
250            else
251              sortedColumnIndizes.RemoveAt(sortedIndex);
252          } else
253            if (newSortOrder != SortOrder.None)
254              sortedColumnIndizes.Add(new KeyValuePair<int, SortOrder>(e.ColumnIndex, newSortOrder));
255          Sort();
256        } else if (e.Button == MouseButtons.Right) {
257          if (Content.ColumnNames.Count() != 0)
258            contextMenu.Show(MousePosition);
259        }
260      }
261    }
262
263    private void Sort() {
264      int[] newSortedIndex = Enumerable.Range(0, Content.Rows - 1).ToArray();
265      if (sortedColumnIndizes.Count != 0) {
266        rowComparer.sortedIndizes = sortedColumnIndizes;
267        rowComparer.matrix = Content;
268        Array.Sort(newSortedIndex, rowComparer);
269      }
270      virtualRowIndizes = newSortedIndex;
271      dataGridView.Invalidate();
272      foreach (DataGridViewColumn col in this.dataGridView.Columns)
273        col.HeaderCell.SortGlyphDirection = SortOrder.None;
274      foreach (KeyValuePair<int, SortOrder> p in sortedColumnIndizes)
275        this.dataGridView.Columns[p.Key].HeaderCell.SortGlyphDirection = p.Value;
276    }
277    #endregion
278
279    private class RowComparer : IComparer<int> {
280      public List<KeyValuePair<int, SortOrder>> sortedIndizes;
281      public IStringConvertibleMatrix matrix;
282      public RowComparer() {
283      }
284
285      public int Compare(int x, int y) {
286        int result = 0;
287        double double1, double2;
288        DateTime dateTime1, dateTime2;
289        string string1, string2;
290
291        foreach (KeyValuePair<int, SortOrder> pair in sortedIndizes) {
292          string1 = matrix.GetValue(x, pair.Key);
293          string2 = matrix.GetValue(y, pair.Key);
294          if (double.TryParse(string1, out double1) && double.TryParse(string2, out double2))
295            result = double1.CompareTo(double2);
296          else if (DateTime.TryParse(string1, out dateTime1) && DateTime.TryParse(string2, out dateTime2))
297            result = dateTime1.CompareTo(dateTime2);
298          else {
299            if (string1 != null)
300              result = string1.CompareTo(string2);
301            else if (string2 != null)
302              result = string2.CompareTo(string1) * -1;
303          }
304          if (pair.Value == SortOrder.Descending)
305            result *= -1;
306          if (result != 0)
307            return result;
308        }
309        return result;
310      }
311    }
312
313    private void ShowHideColumns_Click(object sender, EventArgs e) {
314      new ColumnsVisibilityDialog(this.dataGridView.Columns.Cast<DataGridViewColumn>()).ShowDialog();
315    }
316  }
317}
Note: See TracBrowser for help on using the repository browser.