[14278] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 | using System.Data;
|
---|
| 4 | using System.Linq;
|
---|
| 5 | using System.Text;
|
---|
| 6 | using HeuristicLab.MainForm;
|
---|
| 7 | using HeuristicLab.MainForm.WindowsForms;
|
---|
| 8 | using System.Windows.Forms;
|
---|
| 9 | using HeuristicLab.Common;
|
---|
| 10 |
|
---|
| 11 | namespace HeuristicLab.Data.MoveVectorData.Views
|
---|
| 12 | {
|
---|
| 13 | [View("Stacking Area View")]
|
---|
| 14 | [Content(typeof(StackingArea), IsDefaultView = true)]
|
---|
| 15 | public partial class StackingAreaView : AsynchronousContentView
|
---|
| 16 | {
|
---|
| 17 | protected int[] virtualRowIndices;
|
---|
| 18 |
|
---|
| 19 | public new IStringConvertibleMatrix Content
|
---|
| 20 | {
|
---|
| 21 | get { return (IStringConvertibleMatrix)base.Content; }
|
---|
| 22 | set { base.Content = value; }
|
---|
| 23 | }
|
---|
| 24 |
|
---|
| 25 | public DataGridView DataGridView
|
---|
| 26 | {
|
---|
| 27 | get { return dataGridView; }
|
---|
| 28 | }
|
---|
| 29 |
|
---|
| 30 | public override bool ReadOnly
|
---|
| 31 | {
|
---|
| 32 | get
|
---|
| 33 | {
|
---|
| 34 | if ((Content != null) && Content.ReadOnly) return true;
|
---|
| 35 | return base.ReadOnly;
|
---|
| 36 | }
|
---|
| 37 | set { base.ReadOnly = value; }
|
---|
| 38 | }
|
---|
| 39 |
|
---|
| 40 | public StackingAreaView()
|
---|
| 41 | {
|
---|
| 42 | InitializeComponent();
|
---|
| 43 | }
|
---|
| 44 |
|
---|
| 45 | protected override void DeregisterContentEvents()
|
---|
| 46 | {
|
---|
| 47 | Content.ItemChanged -= new EventHandler<EventArgs<int, int>>(Content_ItemChanged);
|
---|
| 48 | Content.Reset -= new EventHandler(Content_Reset);
|
---|
| 49 | Content.ColumnNamesChanged -= new EventHandler(Content_ColumnNamesChanged);
|
---|
| 50 | Content.RowNamesChanged -= new EventHandler(Content_RowNamesChanged);
|
---|
| 51 | base.DeregisterContentEvents();
|
---|
| 52 | }
|
---|
| 53 | protected override void RegisterContentEvents()
|
---|
| 54 | {
|
---|
| 55 | base.RegisterContentEvents();
|
---|
| 56 | Content.ItemChanged += new EventHandler<EventArgs<int, int>>(Content_ItemChanged);
|
---|
| 57 | Content.Reset += new EventHandler(Content_Reset);
|
---|
| 58 | Content.ColumnNamesChanged += new EventHandler(Content_ColumnNamesChanged);
|
---|
| 59 | Content.RowNamesChanged += new EventHandler(Content_RowNamesChanged);
|
---|
| 60 | }
|
---|
| 61 |
|
---|
| 62 | protected override void OnContentChanged()
|
---|
| 63 | {
|
---|
| 64 | base.OnContentChanged();
|
---|
| 65 | if (Content == null)
|
---|
| 66 | {
|
---|
| 67 | dataGridView.Rows.Clear();
|
---|
| 68 | dataGridView.Columns.Clear();
|
---|
| 69 | virtualRowIndices = new int[0];
|
---|
| 70 | }
|
---|
| 71 | else if (!dataGridView.IsCurrentCellInEditMode)
|
---|
| 72 | {
|
---|
| 73 | UpdateData();
|
---|
| 74 | }
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | protected override void SetEnabledStateOfControls()
|
---|
| 78 | {
|
---|
| 79 | base.SetEnabledStateOfControls();
|
---|
| 80 | dataGridView.Enabled = Content != null;
|
---|
| 81 | dataGridView.ReadOnly = ReadOnly;
|
---|
| 82 | }
|
---|
| 83 |
|
---|
| 84 | protected virtual void UpdateData()
|
---|
| 85 | {
|
---|
| 86 | virtualRowIndices = Enumerable.Range(0, Content.Rows).Reverse().ToArray();
|
---|
| 87 |
|
---|
| 88 | if (Content.Columns == 0 && dataGridView.ColumnCount != Content.Columns && !Content.ReadOnly)
|
---|
| 89 | Content.Columns = dataGridView.ColumnCount;
|
---|
| 90 | else {
|
---|
| 91 | DataGridViewColumn[] columns = new DataGridViewColumn[Content.Columns];
|
---|
| 92 | for (int i = 0; i < columns.Length; ++i)
|
---|
| 93 | {
|
---|
| 94 | var column = new DataGridViewTextBoxColumn();
|
---|
| 95 | column.FillWeight = 1;
|
---|
| 96 | columns[i] = column;
|
---|
| 97 | }
|
---|
| 98 | dataGridView.Columns.Clear();
|
---|
| 99 | dataGridView.Columns.AddRange(columns);
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 | //DataGridViews with rows but no columns are not allowed !
|
---|
| 103 | if (Content.Rows == 0 && dataGridView.RowCount != Content.Rows && !Content.ReadOnly)
|
---|
| 104 | Content.Rows = dataGridView.RowCount;
|
---|
| 105 | else
|
---|
| 106 | dataGridView.RowCount = Content.Rows;
|
---|
| 107 |
|
---|
| 108 | UpdateColumnHeaders();
|
---|
| 109 | UpdateRowHeaders();
|
---|
| 110 |
|
---|
| 111 | dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader);
|
---|
| 112 | dataGridView.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders);
|
---|
| 113 | dataGridView.Enabled = true;
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | public virtual void UpdateColumnHeaders()
|
---|
| 117 | {
|
---|
| 118 | HashSet<string> invisibleColumnNames = new HashSet<string>(dataGridView.Columns.OfType<DataGridViewColumn>()
|
---|
| 119 | .Where(c => !c.Visible && !string.IsNullOrEmpty(c.HeaderText)).Select(c => c.HeaderText));
|
---|
| 120 |
|
---|
| 121 | for (int i = 0; i < dataGridView.ColumnCount; i++)
|
---|
| 122 | {
|
---|
| 123 | if (i < Content.ColumnNames.Count())
|
---|
| 124 | dataGridView.Columns[i].HeaderText = Content.ColumnNames.ElementAt(i);
|
---|
| 125 | else
|
---|
| 126 | dataGridView.Columns[i].HeaderText = "Stack " + (i + 1 - 1);
|
---|
| 127 | dataGridView.Columns[i].Visible = !invisibleColumnNames.Contains(dataGridView.Columns[i].HeaderText);
|
---|
| 128 | }
|
---|
| 129 | }
|
---|
| 130 | public virtual void UpdateRowHeaders()
|
---|
| 131 | {
|
---|
| 132 | int index = dataGridView.FirstDisplayedScrollingRowIndex;
|
---|
| 133 | if (index == -1) index = 0;
|
---|
| 134 | int updatedRows = 0;
|
---|
| 135 | int count = dataGridView.DisplayedRowCount(true);
|
---|
| 136 |
|
---|
| 137 | while (updatedRows < count)
|
---|
| 138 | {
|
---|
| 139 | if (virtualRowIndices[index] < Content.RowNames.Count())
|
---|
| 140 | dataGridView.Rows[index].HeaderCell.Value = Content.RowNames.ElementAt(virtualRowIndices[index]);
|
---|
| 141 | else
|
---|
| 142 | dataGridView.Rows[index].HeaderCell.Value = "Tier " + (count - index - 1);
|
---|
| 143 | if (dataGridView.Rows[index].Visible)
|
---|
| 144 | updatedRows++;
|
---|
| 145 | index++;
|
---|
| 146 | }
|
---|
| 147 | }
|
---|
| 148 |
|
---|
| 149 | private void Content_RowNamesChanged(object sender, EventArgs e)
|
---|
| 150 | {
|
---|
| 151 | if (InvokeRequired)
|
---|
| 152 | Invoke(new EventHandler(Content_RowNamesChanged), sender, e);
|
---|
| 153 | else
|
---|
| 154 | UpdateRowHeaders();
|
---|
| 155 | }
|
---|
| 156 | private void Content_ColumnNamesChanged(object sender, EventArgs e)
|
---|
| 157 | {
|
---|
| 158 | if (InvokeRequired)
|
---|
| 159 | Invoke(new EventHandler(Content_ColumnNamesChanged), sender, e);
|
---|
| 160 | else
|
---|
| 161 | UpdateColumnHeaders();
|
---|
| 162 | }
|
---|
| 163 | private void Content_ItemChanged(object sender, EventArgs<int, int> e)
|
---|
| 164 | {
|
---|
| 165 | if (InvokeRequired)
|
---|
| 166 | Invoke(new EventHandler<EventArgs<int, int>>(Content_ItemChanged), sender, e);
|
---|
| 167 | else
|
---|
| 168 | dataGridView.InvalidateCell(e.Value2, e.Value);
|
---|
| 169 | }
|
---|
| 170 | private void Content_Reset(object sender, EventArgs e)
|
---|
| 171 | {
|
---|
| 172 | if (InvokeRequired)
|
---|
| 173 | Invoke(new EventHandler(Content_Reset), sender, e);
|
---|
| 174 | else
|
---|
| 175 | UpdateData();
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | #region DataGridView Events
|
---|
| 179 | protected virtual void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
|
---|
| 180 | {
|
---|
| 181 | if (!dataGridView.ReadOnly)
|
---|
| 182 | {
|
---|
| 183 | string errorMessage;
|
---|
| 184 | if (Content != null && !Content.Validate(e.FormattedValue.ToString(), out errorMessage))
|
---|
| 185 | {
|
---|
| 186 | e.Cancel = true;
|
---|
| 187 | dataGridView.Rows[e.RowIndex].ErrorText = errorMessage;
|
---|
| 188 | }
|
---|
| 189 | }
|
---|
| 190 | }
|
---|
| 191 | protected virtual void dataGridView_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
|
---|
| 192 | {
|
---|
| 193 | if (!dataGridView.ReadOnly)
|
---|
| 194 | {
|
---|
| 195 | string value = e.Value.ToString();
|
---|
| 196 | int rowIndex = virtualRowIndices[e.RowIndex];
|
---|
| 197 | e.ParsingApplied = Content != null && Content.SetValue(value, rowIndex, e.ColumnIndex);
|
---|
| 198 | if (e.ParsingApplied) e.Value = Content.GetValue(rowIndex, e.ColumnIndex);
|
---|
| 199 | }
|
---|
| 200 | }
|
---|
| 201 | private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
|
---|
| 202 | {
|
---|
| 203 | dataGridView.Rows[e.RowIndex].ErrorText = string.Empty;
|
---|
| 204 | }
|
---|
| 205 | protected virtual void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
|
---|
| 206 | {
|
---|
| 207 | if (Content != null && e.RowIndex < Content.Rows && e.ColumnIndex < Content.Columns)
|
---|
| 208 | {
|
---|
| 209 | int rowIndex = virtualRowIndices[e.RowIndex];
|
---|
| 210 | e.Value = Content.GetValue(rowIndex, e.ColumnIndex);
|
---|
| 211 | }
|
---|
| 212 | }
|
---|
| 213 |
|
---|
| 214 | private void dataGridView_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e)
|
---|
| 215 | {
|
---|
| 216 | this.UpdateRowHeaders();
|
---|
| 217 | }
|
---|
| 218 | private void dataGridView_Resize(object sender, EventArgs e)
|
---|
| 219 | {
|
---|
| 220 | this.UpdateRowHeaders();
|
---|
| 221 | }
|
---|
| 222 |
|
---|
| 223 | protected virtual void dataGridView_KeyDown(object sender, KeyEventArgs e)
|
---|
| 224 | {
|
---|
| 225 | if (!ReadOnly && e.Control && e.KeyCode == Keys.V)
|
---|
| 226 | PasteValuesToDataGridView();
|
---|
| 227 | else if (e.Control && e.KeyCode == Keys.C)
|
---|
| 228 | CopyValuesFromDataGridView();
|
---|
| 229 | }
|
---|
| 230 |
|
---|
| 231 | private void CopyValuesFromDataGridView()
|
---|
| 232 | {
|
---|
| 233 | if (dataGridView.SelectedCells.Count == 0) return;
|
---|
| 234 | StringBuilder s = new StringBuilder();
|
---|
| 235 | int minRowIndex = dataGridView.SelectedCells[0].RowIndex;
|
---|
| 236 | int maxRowIndex = dataGridView.SelectedCells[dataGridView.SelectedCells.Count - 1].RowIndex;
|
---|
| 237 | int minColIndex = dataGridView.SelectedCells[0].ColumnIndex;
|
---|
| 238 | int maxColIndex = dataGridView.SelectedCells[dataGridView.SelectedCells.Count - 1].ColumnIndex;
|
---|
| 239 |
|
---|
| 240 | if (minRowIndex > maxRowIndex)
|
---|
| 241 | {
|
---|
| 242 | int temp = minRowIndex;
|
---|
| 243 | minRowIndex = maxRowIndex;
|
---|
| 244 | maxRowIndex = temp;
|
---|
| 245 | }
|
---|
| 246 | if (minColIndex > maxColIndex)
|
---|
| 247 | {
|
---|
| 248 | int temp = minColIndex;
|
---|
| 249 | minColIndex = maxColIndex;
|
---|
| 250 | maxColIndex = temp;
|
---|
| 251 | }
|
---|
| 252 |
|
---|
| 253 | bool addRowNames = dataGridView.AreAllCellsSelected(false) && Content.RowNames.Count() > 0;
|
---|
| 254 | bool addColumnNames = dataGridView.AreAllCellsSelected(false) && Content.ColumnNames.Count() > 0;
|
---|
| 255 |
|
---|
| 256 | //add colum names
|
---|
| 257 | if (addColumnNames)
|
---|
| 258 | {
|
---|
| 259 | if (addRowNames)
|
---|
| 260 | s.Append('\t');
|
---|
| 261 |
|
---|
| 262 | DataGridViewColumn column = dataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
|
---|
| 263 | while (column != null)
|
---|
| 264 | {
|
---|
| 265 | s.Append(column.HeaderText);
|
---|
| 266 | s.Append('\t');
|
---|
| 267 | column = dataGridView.Columns.GetNextColumn(column, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
|
---|
| 268 | }
|
---|
| 269 | s.Remove(s.Length - 1, 1); //remove last tab
|
---|
| 270 | s.Append(Environment.NewLine);
|
---|
| 271 | }
|
---|
| 272 |
|
---|
| 273 | for (int i = minRowIndex; i <= maxRowIndex; i++)
|
---|
| 274 | {
|
---|
| 275 | if (!dataGridView.Rows[i].Visible) continue;
|
---|
| 276 |
|
---|
| 277 | int rowIndex = this.virtualRowIndices[i];
|
---|
| 278 | if (addRowNames)
|
---|
| 279 | {
|
---|
| 280 | s.Append(Content.RowNames.ElementAt(rowIndex));
|
---|
| 281 | s.Append('\t');
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 | DataGridViewColumn column = dataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
|
---|
| 285 | while (column != null)
|
---|
| 286 | {
|
---|
| 287 | DataGridViewCell cell = dataGridView[column.Index, i];
|
---|
| 288 | if (cell.Selected)
|
---|
| 289 | {
|
---|
| 290 | s.Append(Content.GetValue(rowIndex, column.Index));
|
---|
| 291 | s.Append('\t');
|
---|
| 292 | }
|
---|
| 293 |
|
---|
| 294 | column = dataGridView.Columns.GetNextColumn(column, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
|
---|
| 295 | }
|
---|
| 296 | s.Remove(s.Length - 1, 1); //remove last tab
|
---|
| 297 | s.Append(Environment.NewLine);
|
---|
| 298 | }
|
---|
| 299 | Clipboard.SetText(s.ToString());
|
---|
| 300 | }
|
---|
| 301 |
|
---|
| 302 | protected virtual void PasteValuesToDataGridView()
|
---|
| 303 | {
|
---|
| 304 | string[,] values = SplitClipboardString(Clipboard.GetText());
|
---|
| 305 | int rowIndex = 0;
|
---|
| 306 | int columnIndex = 0;
|
---|
| 307 | if (dataGridView.CurrentCell != null)
|
---|
| 308 | {
|
---|
| 309 | rowIndex = virtualRowIndices[dataGridView.CurrentCell.RowIndex];
|
---|
| 310 | columnIndex = dataGridView.CurrentCell.ColumnIndex;
|
---|
| 311 | }
|
---|
| 312 | if (Content.Rows < values.GetLength(1) + rowIndex) Content.Rows = values.GetLength(1) + rowIndex;
|
---|
| 313 | if (Content.Columns < values.GetLength(0) + columnIndex) Content.Columns = values.GetLength(0) + columnIndex;
|
---|
| 314 |
|
---|
| 315 | for (int row = 0; row < values.GetLength(1); row++)
|
---|
| 316 | {
|
---|
| 317 | for (int col = 0; col < values.GetLength(0); col++)
|
---|
| 318 | {
|
---|
| 319 | Content.SetValue(values[col, values.GetLength(1) - 1 - row], row + rowIndex, col + columnIndex);
|
---|
| 320 | }
|
---|
| 321 | }
|
---|
| 322 | }
|
---|
| 323 | protected string[,] SplitClipboardString(string clipboardText)
|
---|
| 324 | {
|
---|
| 325 | if (clipboardText.EndsWith(Environment.NewLine))
|
---|
| 326 | clipboardText = clipboardText.Remove(clipboardText.Length - Environment.NewLine.Length); //remove last newline constant
|
---|
| 327 | string[,] values = null;
|
---|
| 328 | string[] lines = clipboardText.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
|
---|
| 329 | string[] cells;
|
---|
| 330 | for (int i = 0; i < lines.Length; i++)
|
---|
| 331 | {
|
---|
| 332 | cells = lines[i].Split('\t');
|
---|
| 333 | if (values == null)
|
---|
| 334 | values = new string[cells.Length, lines.Length];
|
---|
| 335 | for (int j = 0; j < cells.Length; j++)
|
---|
| 336 | values[j, i] = string.IsNullOrEmpty(cells[j]) ? string.Empty : cells[j];
|
---|
| 337 | }
|
---|
| 338 | return values;
|
---|
| 339 | }
|
---|
| 340 |
|
---|
| 341 | protected virtual void dataGridView_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
|
---|
| 342 | {
|
---|
| 343 | if (Content == null) return;
|
---|
| 344 | if (e.Button == MouseButtons.Right && Content.ColumnNames.Count() != 0)
|
---|
| 345 | contextMenu.Show(MousePosition);
|
---|
| 346 | }
|
---|
| 347 | }
|
---|
| 348 | #endregion
|
---|
| 349 | }
|
---|