Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Analysis/3.3/DataTable.cs @ 4774

Last change on this file since 4774 was 4774, checked in by swagner, 13 years ago

Fixed exception when an empty data table is viewed with a StringConvertibleMatrixView (#1164)

File size: 8.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.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using HeuristicLab.Collections;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.Analysis {
33  /// <summary>
34  /// A table of data values.
35  /// </summary>
36  [Item("DataTable", "A table of data values.")]
37  [StorableClass]
38  public sealed class DataTable : NamedItem, IStringConvertibleMatrix {
39    public override Image ItemImage {
40      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Performance; }
41    }
42
43    [Storable]
44    private NamedItemCollection<DataRow> rows;
45    public NamedItemCollection<DataRow> Rows {
46      get { return rows; }
47    }
48
49    #region Storing & Cloning
50    [StorableConstructor]
51    private DataTable(bool deserializing) : base(deserializing) { }
52    private DataTable(DataTable original, Cloner cloner)
53      : base(original, cloner) {
54      this.rows = cloner.Clone(original.rows);
55      this.RegisterRowsEvents();
56    }
57    public override IDeepCloneable Clone(Cloner cloner) {
58      return new DataTable(this, cloner);
59    }
60    #endregion
61    public DataTable()
62      : base() {
63      rows = new NamedItemCollection<DataRow>();
64      this.RegisterRowsEvents();
65    }
66    public DataTable(string name)
67      : base(name) {
68      rows = new NamedItemCollection<DataRow>();
69      this.RegisterRowsEvents();
70    }
71    public DataTable(string name, string description)
72      : base(name, description) {
73      rows = new NamedItemCollection<DataRow>();
74      this.RegisterRowsEvents();
75    }
76
77    private void RegisterRowsEvents() {
78      rows.ItemsAdded += new CollectionItemsChangedEventHandler<DataRow>(rows_ItemsAdded);
79      rows.ItemsRemoved += new CollectionItemsChangedEventHandler<DataRow>(rows_ItemsRemoved);
80      rows.ItemsReplaced += new CollectionItemsChangedEventHandler<DataRow>(rows_ItemsReplaced);
81      rows.CollectionReset += new CollectionItemsChangedEventHandler<DataRow>(rows_CollectionReset);
82    }
83    private void rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
84      foreach (DataRow row in e.Items)
85        this.RegisterRowEvents(row);
86      this.OnColumnNamesChanged();
87      this.OnReset();
88    }
89    private void rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
90      foreach (DataRow row in e.Items)
91        this.DeregisterRowEvents(row);
92      this.OnColumnNamesChanged();
93      this.OnReset();
94    }
95    private void rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
96      foreach (DataRow row in e.OldItems)
97        this.DeregisterRowEvents(row);
98      foreach (DataRow row in e.Items)
99        this.RegisterRowEvents(row);
100      this.OnColumnNamesChanged();
101      this.OnReset();
102    }
103    private void rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
104      foreach (DataRow row in e.OldItems)
105        this.DeregisterRowEvents(row);
106      foreach (DataRow row in e.Items)
107        this.RegisterRowEvents(row);
108      this.OnColumnNamesChanged();
109      this.OnReset();
110    }
111
112    private void RegisterRowEvents(DataRow row) {
113      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
114      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
115      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
116      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
117      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
118    }
119    private void DeregisterRowEvents(DataRow row) {
120      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
121      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
122      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
123      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
124      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
125    }
126
127    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
128      this.OnReset();
129    }
130    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
131      this.OnReset();
132    }
133    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
134      this.OnReset();
135    }
136    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
137      this.OnReset();
138    }
139    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
140      this.OnReset();
141    }
142
143    #region IStringConvertibleMatrix Members
144
145    int IStringConvertibleMatrix.Rows {
146      get { return rows.Count == 0 ? 0 : rows.Max(r => r.Values.Count); }
147      set { throw new NotSupportedException(); }
148    }
149    int IStringConvertibleMatrix.Columns {
150      get { return rows.Count; }
151      set { throw new NotSupportedException(); }
152    }
153    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
154      get { return rows.Select(r => r.Name); }
155      set { throw new NotSupportedException(); }
156    }
157    IEnumerable<string> IStringConvertibleMatrix.RowNames {
158      get { return new List<string>(); }
159      set { throw new NotSupportedException(); }
160    }
161
162    bool IStringConvertibleMatrix.SortableView {
163      get { return true; }
164      set { throw new NotSupportedException(); }
165    }
166    bool IStringConvertibleMatrix.ReadOnly {
167      get { return true; }
168    }
169
170    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
171      if (columnIndex < rows.Count) {
172        string columnName = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
173        if (rows.ContainsKey(columnName) && rowIndex < rows[columnName].Values.Count)
174          return rows[columnName].Values[rowIndex].ToString();
175      }
176      return string.Empty;
177    }
178
179    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
180      throw new NotSupportedException();
181    }
182    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
183      throw new NotSupportedException();
184    }
185
186    public event EventHandler<EventArgs<int, int>> ItemChanged;
187    private void OnItemChanged(int rowIndex, int columnIndex) {
188      var handler = ItemChanged;
189      if (handler != null) handler(this, new EventArgs<int, int>(rowIndex, columnIndex));
190      OnToStringChanged();
191    }
192    public event EventHandler Reset;
193    private void OnReset() {
194      var handler = Reset;
195      if (handler != null) handler(this, EventArgs.Empty);
196    }
197    public event EventHandler ColumnNamesChanged;
198    private void OnColumnNamesChanged() {
199      var handler = ColumnNamesChanged;
200      if (handler != null) handler(this, EventArgs.Empty);
201    }
202    public event EventHandler RowNamesChanged;
203    private void OnRowNamesChanged() {
204      var handler = RowNamesChanged;
205      if (handler != null) handler(this, EventArgs.Empty);
206    }
207    public event EventHandler SortableViewChanged;
208    private void OnSortableViewChanged() {
209      var handler = SortableViewChanged;
210      if (handler != null) handler(this, EventArgs.Empty);
211    }
212    #endregion
213  }
214}
Note: See TracBrowser for help on using the repository browser.