source: trunk/sources/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionDataTableView.cs @ 7986

Last change on this file since 7986 was 7986, checked in by mkommend, 9 years ago

#1869: Cleared combo box items if selected data table changes.

File size: 8.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Linq;
25using System.Windows.Forms;
26using HeuristicLab.Analysis;
27using HeuristicLab.Collections;
28using HeuristicLab.Common;
29using HeuristicLab.Core.Views;
30using HeuristicLab.MainForm;
31
32namespace HeuristicLab.Optimization.Views {
33  [View("RunCollection DataTableView")]
34  [Content(typeof(RunCollection), false)]
35  public partial class RunCollectionDataTableView : ItemView {
36    private const string AllDataRows = "All DataRows";
37
38    public RunCollectionDataTableView() {
39      InitializeComponent();
40      runMapping = new Dictionary<IRun, IEnumerable<DataRow>>();
41      combinedDataTable = new DataTable("Combined DataTable", "A data table containing all data rows from all run.");
42      viewHost.Content = combinedDataTable;
43      suppressUpdates = false;
44    }
45
46    public new RunCollection Content {
47      get { return (RunCollection)base.Content; }
48      set { base.Content = value; }
49    }
50
51    private bool suppressUpdates;
52    private readonly Dictionary<IRun, IEnumerable<DataRow>> runMapping;
53    private readonly DataTable combinedDataTable;
54    public DataTable CombinedDataTable {
55      get { return combinedDataTable; }
56    }
57
58    #region Content events
59    protected override void RegisterContentEvents() {
60      base.RegisterContentEvents();
61      Content.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
62      Content.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
63      Content.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
64      Content.UpdateOfRunsInProgressChanged += new EventHandler(Content_UpdateOfRunsInProgressChanged);
65    }
66    protected override void DeregisterContentEvents() {
67      Content.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
68      Content.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
69      Content.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
70      Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
71      base.DeregisterContentEvents();
72    }
73
74    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
75      if (InvokeRequired) {
76        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
77        return;
78      }
79      AddRuns(e.Items);
80    }
81    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
82      if (InvokeRequired) {
83        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e);
84        return;
85      }
86      RemoveRuns(e.Items);
87    }
88    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
89      if (InvokeRequired) {
90        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e);
91        return;
92      }
93      RemoveRuns(e.OldItems);
94      AddRuns(e.Items);
95    }
96    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
97      if (InvokeRequired) {
98        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
99        return;
100      }
101      suppressUpdates = Content.UpdateOfRunsInProgress;
102      if (!suppressUpdates) UpdateRuns(Content);
103    }
104
105    private void RegisterRunEvents(IRun run) {
106      run.Changed += new System.EventHandler(run_Changed);
107    }
108    private void DeregisterRunEvents(IRun run) {
109      run.Changed -= new System.EventHandler(run_Changed);
110    }
111    private void run_Changed(object sender, EventArgs e) {
112      if (suppressUpdates) return;
113      IRun run = (IRun)sender;
114      UpdateRuns(run.ToEnumerable());
115
116    }
117    #endregion
118
119    protected override void OnContentChanged() {
120      base.OnContentChanged();
121      dataTableComboBox.Items.Clear();
122      dataRowComboBox.Items.Clear();
123      combinedDataTable.Rows.Clear();
124      runMapping.Clear();
125
126      if (Content != null) {
127        UpdateDataTableComboBox();
128      }
129    }
130
131    private void RebuildCombinedDataTable() {
132      RemoveRuns(Content);
133      AddRuns(Content);
134    }
135
136    private void AddRuns(IEnumerable<IRun> runs) {
137      foreach (var run in runs) {
138        runMapping[run] = ExtractDataRowsFromRun(run).ToList();
139        RegisterRunEvents(run);
140      }
141      var dataRows = runs.Where(r => r.Visible && runMapping.ContainsKey(r)).SelectMany(r => runMapping[r]);
142      combinedDataTable.Rows.AddRange(dataRows);
143    }
144    private void RemoveRuns(IEnumerable<IRun> runs) {
145      var dataRows = runs.Where(r => runMapping.ContainsKey(r)).SelectMany(r => runMapping[r]).ToList();
146      foreach (var run in runs) {
147        if (!runMapping.ContainsKey(run)) continue;
148        runMapping.Remove(run);
149        DeregisterRunEvents(run);
150      }
151      combinedDataTable.Rows.RemoveRange(dataRows);
152    }
153
154    private void UpdateRuns(IEnumerable<IRun> runs) {
155      if (suppressUpdates) return;
156      foreach (var run in runs) {
157        //update color
158        foreach (var dataRow in runMapping[run]) {
159          dataRow.VisualProperties.Color = run.Color;
160        }
161        //update visibility - remove and add all rows to keep the same order as before
162        combinedDataTable.Rows.Clear();
163        combinedDataTable.Rows.AddRange(runMapping.Where(mapping => mapping.Key.Visible).SelectMany(mapping => mapping.Value));
164      }
165    }
166
167    private int rowNumber = 0;
168    private IEnumerable<DataRow> ExtractDataRowsFromRun(IRun run) {
169      string resultName = (string)dataTableComboBox.SelectedItem;
170      string rowName = (string)dataRowComboBox.SelectedItem;
171      if (!run.Results.ContainsKey(resultName)) yield break;
172
173      DataTable dataTable = (DataTable)run.Results[resultName];
174      foreach (var dataRow in dataTable.Rows) {
175        if (dataRow.Name != rowName && rowName != AllDataRows) continue;
176        rowNumber++;
177        var clonedRow = (DataRow)dataRow.Clone();
178        //row names must be unique -> add incremented number to the row name
179        clonedRow.Name = run.Name + "." + dataRow.Name + rowNumber;
180        clonedRow.VisualProperties.DisplayName = run.Name + "." + dataRow.Name;
181        clonedRow.VisualProperties.Color = run.Color;
182        yield return clonedRow;
183      }
184    }
185
186    private void UpdateDataTableComboBox() {
187      dataTableComboBox.Items.Clear();
188      var dataTables = (from run in Content
189                        from result in run.Results
190                        where result.Value is DataTable
191                        select result.Key).Distinct().ToArray();
192
193      dataTableComboBox.Items.AddRange(dataTables);
194      if (dataTableComboBox.Items.Count > 0) dataTableComboBox.SelectedItem = dataTableComboBox.Items[0];
195    }
196
197    private void UpdateDataRowComboBox() {
198      dataRowComboBox.Items.Clear();
199      string resultName = (string)dataTableComboBox.SelectedItem;
200      var dataTables = from run in Content
201                       where run.Results.ContainsKey(resultName)
202                       select run.Results[resultName] as DataTable;
203      var rowNames = (from dataTable in dataTables
204                      from row in dataTable.Rows
205                      select row.Name).Distinct().ToArray();
206
207      dataRowComboBox.Items.AddRange(rowNames);
208      dataRowComboBox.Items.Add(AllDataRows);
209      if (dataRowComboBox.Items.Count > 0) dataRowComboBox.SelectedItem = dataRowComboBox.Items[0];
210    }
211
212    private void dataTableComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
213      UpdateDataRowComboBox();
214    }
215    private void dataRowComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
216      RebuildCombinedDataTable();
217    }
218  }
219}
Note: See TracBrowser for help on using the repository browser.