/// <summary> /// Called when user clicks on a file name. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void OnFileBrowseClick(object sender, GridCellsChangedArgs e) { string filterString = ""; string[] fileFilters = e.ChangedCells[0].DropDownStrings; if (fileFilters != null) { for (int i = 0; i < fileFilters.Length; i++) { if (i > 0) { filterString += '|'; } filterString += fileFilters[i]; } } else { filterString = "All files (*.*)|*.*"; } string fileName = explorerPresenter.MainPresenter.AskUserForOpenFileName(filterString); if (fileName != null) { e.ChangedCells[0].Value = fileName; OnCellValueChanged(sender, e); PopulateGrid(model); } }
/// <summary> /// User has changed the value of a cell. /// </summary> /// <param name="sender">Sender object</param> /// <param name="e">Event parameters</param> private void OnCellValueChanged(object sender, GridCellsChangedArgs e) { presenter.CommandHistory.ModelChanged -= OnModelChanged; foreach (IGridCell cell in e.ChangedCells) { try { if (e.InvalidValue) { throw new Exception("The value you entered was not valid for its datatype."); } if (cell.RowIndex < properties.Count) { SetPropertyValue(properties[cell.RowIndex], cell.Value); } } catch (Exception ex) { presenter.MainPresenter.ShowError(ex); } } presenter.CommandHistory.ModelChanged += OnModelChanged; }
/// <summary> /// User has changed the value of a cell. /// </summary> /// <param name="sender">Sender object</param> /// <param name="e">Event parameters</param> private void OnCellValueChanged(object sender, GridCellsChangedArgs e) { this.explorerPresenter.CommandHistory.ModelChanged -= this.OnModelChanged; foreach (GridCellChangedArgs cell in e.ChangedCells) { try { //need to subtract one for column index of the cell due to description column Model childmodel = this.childrenWithSameType[cell.ColIndex - 1] as Model; VariableProperty property = properties[cell.ColIndex - 1][cell.RowIndex]; object newValue = GetNewCellValue(property, cell.NewValue); this.SetPropertyValue(childmodel, property, newValue); if (newValue.GetType().IsEnum) { newValue = VariableProperty.GetEnumDescription(newValue as Enum); } grid.DataSource.Rows[cell.RowIndex][cell.ColIndex] = newValue; } catch (Exception ex) { explorerPresenter.MainPresenter.ShowError(ex); } } this.explorerPresenter.CommandHistory.ModelChanged += this.OnModelChanged; }
/// <summary> /// User has changed the value of a cell. Validate the change /// apply the change. /// </summary> /// <param name="sender">Sender object</param> /// <param name="args">Event parameters</param> private void OnCellsChanged(object sender, GridCellsChangedArgs args) { List <ChangeProperty.Property> changes = new List <ChangeProperty.Property>(); foreach (GridCellChangedArgs cell in args.ChangedCells) { if (cell.NewValue == cell.OldValue) { continue; // silently fail } // If there are multiple changed cells, each change will be // individually undoable. IVariable property = GetProperty(cell.RowIndex, cell.ColIndex); if (property == null) { continue; } // Parse the input string to the appropriate type. object newValue = GetNewPropertyValue(property, cell); // Update the value of the model's property. SetPropertyValue(property, newValue); // Update the value shown in the grid. grid.DataSource.Rows[cell.RowIndex][cell.ColIndex] = GetCellValue(property, cell.RowIndex, cell.ColIndex); } UpdateReadOnlyProperties(); }
/// <summary> /// Updates the contents of the grid to reflect changes made by /// the user. /// </summary> /// <param name="e">Event arguments.</param> private void ApplyChangesToGrid(GridCellsChangedArgs e) { foreach (GridCellChangedArgs cell in e.ChangedCells) { // Each cell in the grid is a number (of type double). object newValue = ReflectionUtilities.StringToObject(typeof(double), cell.NewValue); grid.DataSource.Rows[cell.RowIndex][cell.ColIndex] = newValue; } }
/// <summary> /// User has changed the value of a cell. /// </summary> /// <param name="sender">Sender object.</param> /// <param name="e">Event arguments.</param> private void OnCellValueChanged1(object sender, GridCellsChangedArgs e) { foreach (GridCellChangedArgs cell in e.ChangedCells) { tables[0].Rows[cell.RowIndex][cell.ColIndex] = cell.NewValue; } ChangeProperty cmd = new ChangeProperty(tableModel, "Tables", tables); presenter.CommandHistory.Add(cmd); }
/// <summary>User has changed the value of one or more cells in the profile grid.</summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void OnCellValueChanged(object sender, GridCellsChangedArgs e) { bool refreshGrid = false; foreach (var changedCell in e.ChangedCells) { if (!Convert.IsDBNull(changedCell.Value)) { GridColumnMetaData column = columnMetadata[changedCell.ColumnIndex]; Array array = column.Values as Array; int numValues = e.ChangedCells.Max(cell => cell.RowIndex); if (array == null) { array = Array.CreateInstance(column.ColumnDataType, numValues + 1); } // If we've added a new row, the column metadata will not contain an entry // for this row (the array will be too short). if (array.Length <= changedCell.RowIndex) { Array newArray = Array.CreateInstance(column.ColumnDataType, numValues + 1); array.CopyTo(newArray, 0); array = newArray; } array.SetValue(Convert.ChangeType(changedCell.Value, column.ColumnDataType), changedCell.RowIndex); column.Values = array; column.ValuesHaveChanged = true; if (column.AddTotalToColumnName) { refreshGrid = true; } } else { GridColumnMetaData column = columnMetadata[changedCell.ColumnIndex]; Array array = column.Values as Array; if (column.ColumnDataType == typeof(double) || column.ColumnDataType == typeof(float)) { array.SetValue(double.NaN, changedCell.RowIndex); } column.Values = array; column.ValuesHaveChanged = true; } } if (refreshGrid) { // refresh DataSource = CreateTable(); FormatGrid(); } CellsHaveChanged?.Invoke(this, new EventArgs()); }
/// <summary> /// Called when user clicks on a file name. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void OnFileBrowseClick(object sender, GridCellsChangedArgs e) { string fileName = explorerPresenter.MainPresenter.AskUserForOpenFileName("Select file"); if (fileName != null) { e.ChangedCells[0].Value = fileName; OnCellValueChanged(sender, e); PopulateGrid(model); } }
/// <summary> /// Called when user clicks on a file name. /// Does creation of the dialog belong here, or in the view? /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void OnFileBrowseClick(object sender, GridCellsChangedArgs e) { string fileName = ViewBase.AskUserForFileName("Select file path", string.Empty, Gtk.FileChooserAction.Open, e.ChangedCells[0].Value.ToString()); if (fileName != null && fileName != e.ChangedCells[0].Value.ToString()) { e.ChangedCells[0].Value = fileName; this.OnCellValueChanged(sender, e); this.PopulateGrid(this.model); } }
/// <summary> /// Invoked whenever one of the grids is modified. /// Propagates the signal up to the presenter. /// </summary> /// <param name="sender">Sender object.</param> /// <param name="args">Event arguments.</param> private void GridCellEdited(object sender, GridCellsChangedArgs args) { try { OnCellEndEdit?.Invoke(sender, args); } catch (Exception err) { ShowError(err); } }
/// <summary> /// User has changed the value of a cell. /// </summary> /// <param name="col">The column index of the cell that has changed</param> /// <param name="row">The row index of the cell that has changed</param> /// <param name="oldValue">The cell value before the user changed it</param> /// <param name="newValue">The cell value the user has entered</param> private void OnCellValueChanged(object sender, GridCellsChangedArgs e) { this.explorerPresenter.CommandHistory.ModelChanged -= this.OnModelChanged; foreach (IGridCell cell in e.ChangedCells) { this.SetPropertyValue(this.properties[cell.RowIndex], cell.Value); } this.explorerPresenter.CommandHistory.ModelChanged += this.OnModelChanged; }
/// <summary> /// User has clicked a cell. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="DataGridViewCellEventArgs"/> instance containing the event data.</param> private void OnCellContentClick(object sender, DataGridViewCellEventArgs e) { IGridCell cell = this.GetCell(e.ColumnIndex, e.RowIndex); if (cell != null && cell.EditorType == EditorTypeEnum.Button) { GridCellsChangedArgs cellClicked = new GridCellsChangedArgs(); cellClicked.ChangedCells = new List <IGridCell>(); cellClicked.ChangedCells.Add(cell); ButtonClick(this, cellClicked); } }
/// <summary> /// User has changed the value of one or more cells in the profile grid. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void OnVariablesGridCellValueChanged(object sender, GridCellsChangedArgs e) { this.SaveGrid(); // Refresh all calculated columns. this.RefreshCalculatedColumns(); // Refresh the graph. if (this.graph != null) { this.graphPresenter.DrawGraph(); } }
/// <summary> /// Edit the cell /// </summary> /// <param name="sender">The sender object</param> /// <param name="e">Event arguments</param> private void OnCellEndEdit(object sender, GridCellsChangedArgs e) { GridView grid = sender as GridView; // fixme - need some (any!) data validation but it will // require a partial rewrite of TreeProxy. foreach (GridCellChangedArgs cell in e.ChangedCells) { grid.DataSource.Rows[cell.RowIndex][cell.ColIndex] = cell.NewValue; } SaveTable(); AttachData(); }
/// <summary> /// User has changed the value of a cell. /// </summary> /// <param name="col">The column index of the cell that has changed</param> /// <param name="row">The row index of the cell that has changed</param> /// <param name="oldValue">The cell value before the user changed it</param> /// <param name="newValue">The cell value the user has entered</param> private void OnCellValueChanged(object sender, GridCellsChangedArgs e) { this.explorerPresenter.CommandHistory.ModelChanged -= this.OnModelChanged; foreach (IGridCell cell in e.ChangedCells) { if (e.invalidValue) { this.explorerPresenter.MainPresenter.ShowMsgDialog("The value you entered was not valid for its datatype", "Invalid entry", Gtk.MessageType.Warning, Gtk.ButtonsType.Ok); } this.SetPropertyValue(this.properties[cell.RowIndex], cell.Value); } this.explorerPresenter.CommandHistory.ModelChanged += this.OnModelChanged; }
/// <summary> /// Updates the contents of the grid to reflect changes made by /// the user. /// </summary> /// <param name="e">Event arguments.</param> private void ApplyChangesToGrid(GridCellsChangedArgs e) { foreach (GridCellChangedArgs cell in e.ChangedCells) { // Each cell in the grid is a number (of type double). object newValue = ReflectionUtilities.StringToObject(typeof(double), cell.NewValue); grid.DataSource.Rows[cell.RowIndex][cell.ColIndex] = newValue; // Ensure that the grid has an extra (empty) row at the bottom. while (grid.RowCount <= cell.RowIndex + 1) { grid.RowCount++; } } }
/// <summary> /// User has changed the value of a cell. /// </summary> /// <param name="sender">Sender object.</param> /// <param name="e">Event arguments.</param> private void OnCellValueChanged1(object sender, GridCellsChangedArgs e) { foreach (GridCellChangedArgs cell in e.ChangedCells) { try { tables[0] = view.Grid1.DataSource; ChangeProperty cmd = new ChangeProperty(tableModel, "Tables", tables); presenter.CommandHistory.Add(cmd); } catch (Exception ex) { presenter.MainPresenter.ShowError(ex); } } }
/// <summary> /// User has finished editing a cell. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void OnCellValueChanged(object sender, DataGridViewCellEventArgs e) { if (this.userEditingCell) { object oldValue = this.valueBeforeEdit; this.userEditingCell = false; // Make sure our table has enough rows. object newValue = this.Grid[e.ColumnIndex, e.RowIndex].Value; if (newValue == null) { newValue = DBNull.Value; } while (this.DataSource != null && e.RowIndex >= this.DataSource.Rows.Count) { this.DataSource.Rows.Add(this.DataSource.NewRow()); } // Put the new value into the table on the correct row. if (this.DataSource != null) { try { this.DataSource.Rows[e.RowIndex][e.ColumnIndex] = newValue; } catch (Exception) { } } if (this.valueBeforeEdit != null && this.valueBeforeEdit.GetType() == typeof(string) && newValue == null) { newValue = string.Empty; } if (this.CellsChanged != null && this.valueBeforeEdit != newValue) { GridCellsChangedArgs args = new GridCellsChangedArgs(); args.ChangedCells = new List <IGridCell>(); args.ChangedCells.Add(this.GetCell(e.ColumnIndex, e.RowIndex)); this.CellsChanged(this, args); } } }
/// <summary> /// User has clicked a cell. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="DataGridViewCellEventArgs"/> instance containing the event data.</param> private void OnCellContentClick(object sender, DataGridViewCellEventArgs e) { IGridCell cell = this.GetCell(e.ColumnIndex, e.RowIndex); if (cell != null && cell.EditorType == EditorTypeEnum.Button) { DataGridViewButtonCell gridCell = Grid[e.ColumnIndex, e.RowIndex] as DataGridViewButtonCell; if (gridCell != null) { cell.DropDownStrings = (string[])gridCell.Tag; } GridCellsChangedArgs cellClicked = new GridCellsChangedArgs(); cellClicked.ChangedCells = new List <IGridCell>(); cellClicked.ChangedCells.Add(cell); ButtonClick(this, cellClicked); } }
/// <summary> /// Called when user clicks on a file name. /// </summary> /// <remarks> /// Does creation of the dialog belong here, or in the view? /// </remarks> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void OnFileBrowseClick(object sender, GridCellsChangedArgs e) { IFileDialog fileChooser = new FileDialog() { Action = FileDialog.FileActionType.Open, Prompt = "Select file path", InitialDirectory = e.ChangedCells[0].Value.ToString() }; string fileName = fileChooser.GetFile(); if (fileName != null && fileName != e.ChangedCells[0].Value.ToString()) { e.ChangedCells[0].Value = fileName; OnCellValueChanged(sender, e); PopulateGrid(model); } }
/// <summary> /// User has changed the value of one or more cells in the profile grid. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void OnVariablesGridCellValueChanged(object sender, GridCellsChangedArgs e) { // Apply the changes to the grid. ApplyChangesToGrid(e); // Save the changed data back to the model. this.SaveGrid(); // Refresh all calculated columns. this.RefreshCalculatedColumns(); // Refresh the graph. if (this.graph != null) { this.graphPresenter.DrawGraph(); } }
/// <summary> /// User has changed the value of a cell. /// </summary> /// <param name="sender">Sender object.</param> /// <param name="e">Event arguments.</param> private void OnCellValueChanged1(object sender, GridCellsChangedArgs e) { foreach (IGridCell cell in e.ChangedCells) { try { if (e.InvalidValue) { throw new Exception("The value you entered was not valid for its datatype."); } tables[0] = view.Grid1.DataSource; ChangeProperty cmd = new ChangeProperty(tableModel, "Tables", tables); presenter.CommandHistory.Add(cmd); } catch (Exception ex) { presenter.MainPresenter.ShowError(ex); } } }
/// <summary> /// Invoked whenever the user modifies the contents of the grid. /// </summary> /// <param name="sender">Sender object.</param> /// <param name="args">Event arguments.</param> private void OnGridChanged(object sender, GridCellsChangedArgs args) { try { if (args.InvalidValue) { throw new Exception("The value you entered was not valid for its datatype."); } foreach (IGridCell cell in args.ChangedCells) { int index = GetModelIndex(cell.RowIndex); IModel removalType = Apsim.Child(model, grid.GetCell(0, index).Value.ToString()); if (removalType != null) { List <MemberInfo> members = PropertyPresenter.GetMembers(removalType); MemberInfo member = members[cell.RowIndex - index - 1]; IVariable property = null; if (member is PropertyInfo) { property = new VariableProperty(model, member as PropertyInfo); } else if (member is FieldInfo) { property = new VariableField(model, member as FieldInfo); } else { throw new Exception(string.Format("Unable to find property {0} in model {1}", grid.GetCell(0, cell.RowIndex).Value.ToString(), removalType.Name)); } object value = PropertyPresenter.FormatValueForProperty(property, cell.Value); ChangeProperty command = new ChangeProperty(removalType, property.Name, value); presenter.CommandHistory.Add(command); } } } catch (Exception err) { presenter.MainPresenter.ShowError(err); } }
/// <summary> /// User has changed the value of a cell. Validate the change /// apply the change. /// </summary> /// <param name="sender">Sender object</param> /// <param name="args">Event parameters</param> private void OnCellsChanged(object sender, GridCellsChangedArgs args) { List <ChangeProperty.Property> changes = new List <ChangeProperty.Property>(); foreach (GridCellChangedArgs cell in args.ChangedCells) { if (cell.NewValue == cell.OldValue) { continue; // silently fail } // If there are multiple changed cells, each change will be // individually undoable. IVariable property = GetProperty(cell.RowIndex, cell.ColIndex); if (property == null) { continue; } // Parse the input string to the appropriate type. object newValue = GetNewPropertyValue(property, cell); // Update the value of the model's property. SetPropertyValue(property, newValue); // Update the value shown in the grid. object val = GetCellValue(property, cell.RowIndex, cell.ColIndex); // Special handling for enumerations, as we want to display the description, not the value if (val.GetType().IsEnum) { val = VariableProperty.GetEnumDescription(val as Enum); } grid.DataSource.Rows[cell.RowIndex][cell.ColIndex] = val; } UpdateReadOnlyProperties(); }
/// <summary> /// User has changed the value of a cell. /// </summary> /// <param name="sender">Sender object</param> /// <param name="e">Event parameters</param> private void OnCellValueChanged(object sender, GridCellsChangedArgs e) { this.explorerPresenter.CommandHistory.ModelChanged -= this.OnModelChanged; foreach (IGridCell cell in e.ChangedCells) { if (e.InvalidValue) { this.explorerPresenter.MainPresenter.ShowMsgDialog("The value you entered was not valid for its datatype", "Invalid entry", Gtk.MessageType.Warning, Gtk.ButtonsType.Ok); } try { //need to subtract one for column index of the cell due to description column Model childmodel = this.childrenWithSameType[cell.ColumnIndex - 1] as Model; this.SetPropertyValue(childmodel, this.properties[cell.ColumnIndex - 1][cell.RowIndex], cell.Value); } catch (Exception ex) { explorerPresenter.MainPresenter.ShowError(ex); } } this.explorerPresenter.CommandHistory.ModelChanged += this.OnModelChanged; }
/// <summary> /// User has clicked a cell. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="DataGridViewCellEventArgs"/> instance containing the event data.</param> private void OnCellContentClick(object sender, DataGridViewCellEventArgs e) { IGridCell cell = this.GetCell(e.ColumnIndex, e.RowIndex); if (cell != null && cell.EditorType == EditorTypeEnum.Button) { GridCellsChangedArgs cellClicked = new GridCellsChangedArgs(); cellClicked.ChangedCells = new List<IGridCell>(); cellClicked.ChangedCells.Add(cell); ButtonClick(this, cellClicked); } }
/// <summary> /// Called when user clicks on a file name. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void OnFileBrowseClick(object sender, GridCellsChangedArgs e) { string filterString = ""; string[] fileFilters = e.ChangedCells[0].DropDownStrings; if (fileFilters != null) { for (int i = 0; i < fileFilters.Length; i++) { if (i > 0) filterString += '|'; filterString += fileFilters[i]; } } else filterString = "All files (*.*)|*.*"; string fileName = explorerPresenter.MainPresenter.AskUserForOpenFileName(filterString); if (fileName != null) { e.ChangedCells[0].Value = fileName; OnCellValueChanged(sender, e); PopulateGrid(model); } }
/// <summary> /// User has changed the value of a cell. Validate the change /// apply the change. /// </summary> /// <param name="sender">Sender object</param> /// <param name="args">Event parameters</param> private void OnCellsChanged(object sender, GridCellsChangedArgs args) { List <ChangeProperty.Property> changes = new List <ChangeProperty.Property>(); // If all cells are being set to null, and the number of changed // cells is a multiple of the number of properties, we could be // deleting an entire row (or rows). In this case, we need // different logic, to resize all of the arrays. bool deletedRow = false; if (args.ChangedCells.All(c => c.NewValue == null) && args.ChangedCells.Count % properties.Where(p => !p.IsReadOnly).Count() == 0) { // Get list of distinct rows which have been changed. int[] changedRows = args.ChangedCells.Select(c => c.RowIndex).Distinct().ToArray(); List <int> rowsToDelete = new List <int>(); foreach (int row in changedRows) { // Get columns which have been changed in this row. var changesInRow = args.ChangedCells.Where(c => c.RowIndex == row); int[] columns = changesInRow.Select(c => c.ColIndex).ToArray(); // If all non-readonly properties have been set to null in this row, // delete the row. bool deleteRow = true; for (int i = 0; i < properties.Count; i++) { if (!properties[i].IsReadOnly && !columns.Contains(i)) { deleteRow = false; } } if (deleteRow) { // We can't delete the row now - what if the user has deleted // multiple rows at once (this is possible via shift-clicking). // We need one change property command per property. Otherwise, // only the last command will have an effect. deletedRow = true; rowsToDelete.Add(row); } } if (rowsToDelete.Count > 0) { // This assumes that only consecutive rows can be deleted together. // ie the user can shift click multiple rows and hit delete to delete // more than 1 row. They cannot ctrl click to select non-adjacent rows. int from = rowsToDelete.Min(); int to = rowsToDelete.Max(); changes.AddRange(DeleteRows(from, to)); // Remove cells in deleted rows from list of changed cells, // as we've already dealt with them. args.ChangedCells = args.ChangedCells.Where(c => !rowsToDelete.Contains(c.RowIndex)).ToList(); } } foreach (var column in args.ChangedCells.GroupBy(c => c.ColIndex)) { VariableProperty property = properties[column.Key]; if (property == null || property.IsReadOnly) { continue; } // Get a deep copy of the property value. Array newArray = property.Value as Array; if (newArray == null && property.Value != null) { continue; } newArray = Clone(newArray, property.DataType.GetElementType()); // It's possible to change multiple values in the same column // simultaneously via multi-selection. If we just add a change // property command for each individual change, later changes // would overwrite the earlier changes. We need to merge all // changes to a single column into a single command then move // onto the next column. foreach (GridCellChangedArgs change in column) { if (change.NewValue == change.OldValue) { continue; // silently fail } // If the user has entered data into a new row, we will need to // resize all of the array properties. changes.AddRange(CheckArrayLengths(change)); object element = ReflectionUtilities.StringToObject(property.DataType.GetElementType(), change.NewValue); if (newArray.Length <= change.RowIndex) { Resize(ref newArray, change.RowIndex + 1); } newArray.SetValue(element, change.RowIndex); } changes.Add(new ChangeProperty.Property(property.Object, property.Name, newArray)); } // Apply all changes to the model in a single undoable command. SetPropertyValue(new ChangeProperty(changes)); // Update the value shown in the grid. This needs to happen after // we have applied changes to the model for obvious reasons. foreach (GridCellChangedArgs cell in args.ChangedCells) { // Add new rows to the view's grid if necessary. while (grid.RowCount <= cell.RowIndex + 1) { grid.RowCount++; } grid.DataSource.Rows[cell.RowIndex][cell.ColIndex] = GetCellValue(cell.RowIndex, cell.ColIndex); } // If the user deleted an entire row, do a full refresh of the // grid. Otherwise, only refresh read-only columns (PAWC). if (deletedRow) { PopulateGrid(model); } else { UpdateReadOnlyProperties(); } }
/// <summary> /// User has changed the value of one or more cells in the profile grid. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void OnProfileGridCellValueChanged(object sender, GridCellsChangedArgs e) { this.SaveGrid(); // Refresh all calculated columns. this.RefreshCalculatedColumns(); // Refresh the graph. if (this.graph != null) { this.graphPresenter.DrawGraph(); } }
/// <summary> /// User has clicked a cell. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="DataGridViewCellEventArgs"/> instance containing the event data.</param> private void OnCellContentClick(object sender, DataGridViewCellEventArgs e) { IGridCell cell = this.GetCell(e.ColumnIndex, e.RowIndex); if (cell != null && cell.EditorType == EditorTypeEnum.Button) { DataGridViewButtonCell gridCell = Grid[e.ColumnIndex, e.RowIndex] as DataGridViewButtonCell; if (gridCell != null) cell.DropDownStrings = (string[])gridCell.Tag; GridCellsChangedArgs cellClicked = new GridCellsChangedArgs(); cellClicked.ChangedCells = new List<IGridCell>(); cellClicked.ChangedCells.Add(cell); ButtonClick(this, cellClicked); } }
/// <summary> /// User has finished editing a cell. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void OnCellValueChanged(object sender, EditedArgs e) { if (this.userEditingCell) { IGridCell where = GetCurrentCell; object oldValue = this.valueBeforeEdit; this.userEditingCell = false; // Make sure our table has enough rows. string newtext = e.NewText; object newValue = oldValue; if (newtext == null) { newValue = DBNull.Value; } Type dataType = oldValue.GetType(); if (dataType == typeof(string)) newValue = newtext; else if (dataType == typeof(double)) { double numval; if (Double.TryParse(newtext, out numval)) newValue = numval; else newValue = Double.NaN; } else if (dataType == typeof(Single)) { Single numval; if (Single.TryParse(newtext, out numval)) newValue = numval; else newValue = Single.NaN; } else if (dataType == typeof(int)) { int numval; if (int.TryParse(newtext, out numval)) newValue = numval; else newValue = Single.NaN; } else if (dataType == typeof(DateTime)) { DateTime dateval; if (DateTime.TryParse(newtext, out dateval)) newValue = dateval; } while (this.DataSource != null && where.RowIndex >= this.DataSource.Rows.Count) { this.DataSource.Rows.Add(this.DataSource.NewRow()); } // Put the new value into the table on the correct row. if (this.DataSource != null) { try { this.DataSource.Rows[where.RowIndex][where.ColumnIndex] = newValue; } catch (Exception) { } } if (this.valueBeforeEdit != null && this.valueBeforeEdit.GetType() == typeof(string) && newValue == null) { newValue = string.Empty; } if (this.CellsChanged != null && this.valueBeforeEdit != newValue) { GridCellsChangedArgs args = new GridCellsChangedArgs(); args.ChangedCells = new List<IGridCell>(); args.ChangedCells.Add(this.GetCell(where.ColumnIndex, where.RowIndex)); this.CellsChanged(this, args); } } }
/// <summary> /// User is about to edit a cell. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void OnCellBeginEdit(object sender, EditingStartedArgs e) { this.userEditingCell = true; IGridCell where = GetCurrentCell; if (where.RowIndex >= DataSource.Rows.Count) { for (int i = DataSource.Rows.Count; i <= where.RowIndex; i++) { DataRow row = DataSource.NewRow(); DataSource.Rows.Add(row); } } this.valueBeforeEdit = this.DataSource.Rows[where.RowIndex][where.ColumnIndex]; Type dataType = this.valueBeforeEdit.GetType(); if (dataType == typeof(DateTime)) { Dialog dialog = new Dialog("Select date", gridview.Toplevel as Window, DialogFlags.DestroyWithParent); dialog.SetPosition(WindowPosition.None); VBox topArea = dialog.VBox; topArea.PackStart(new HBox()); Calendar calendar = new Calendar(); calendar.DisplayOptions = CalendarDisplayOptions.ShowHeading | CalendarDisplayOptions.ShowDayNames | CalendarDisplayOptions.ShowWeekNumbers; calendar.Date = (DateTime)this.valueBeforeEdit; topArea.PackStart(calendar, true, true, 0); dialog.ShowAll(); dialog.Run(); // What SHOULD we do here? For now, assume that if the user modified the date in the calendar dialog, // the resulting date is what they want. Otherwise, keep the text-editing (Entry) widget active, and // let the user enter a value manually. if (calendar.Date != (DateTime)this.valueBeforeEdit) { DateTime date = calendar.GetDate(); this.DataSource.Rows[where.RowIndex][where.ColumnIndex] = date; CellRendererText render = sender as CellRendererText; if (render != null) { render.Text = String.Format("{0:d}", date); if (e.Editable is Entry) { (e.Editable as Entry).Text = render.Text; (e.Editable as Entry).Destroy(); this.userEditingCell = false; if (this.CellsChanged != null) { GridCellsChangedArgs args = new GridCellsChangedArgs(); args.ChangedCells = new List<IGridCell>(); args.ChangedCells.Add(this.GetCell(where.ColumnIndex, where.RowIndex)); this.CellsChanged(this, args); } } } } dialog.Destroy(); } }
/// <summary> /// User has changed the value of a cell. Validate the change /// apply the change. /// </summary> /// <param name="sender">Sender object</param> /// <param name="args">Event parameters</param> private void OnCellsChanged(object sender, GridCellsChangedArgs args) { List <ChangeProperty.Property> changes = new List <ChangeProperty.Property>(); foreach (var column in args.ChangedCells.GroupBy(c => c.ColIndex)) { VariableProperty property = properties[column.Key]; if (property == null || property.IsReadOnly) { continue; } // Get a deep copy of the property value. Array newArray = property.Value as Array; if (newArray == null && property.Value != null) { continue; } newArray = Clone(newArray, property.DataType.GetElementType()); // It's possible to change multiple values in the same column // simultaneously via multi-selection. If we just add a change // property command for each individual change, later changes // would overwrite the earlier changes. We need to merge all // changes to a single column into a single command then move // onto the next column. foreach (GridCellChangedArgs change in column) { if (change.NewValue == change.OldValue) { continue; // silently fail } if (change.RowIndex >= newArray.Length && string.IsNullOrEmpty(change.NewValue)) { continue; } // If the user has entered data into a new row, we will need to // resize all of the array properties. changes.AddRange(CheckArrayLengths(change)); // Need to convert user input to a string using the current // culture. object element = ReflectionUtilities.StringToObject(property.DataType.GetElementType(), change.NewValue, CultureInfo.CurrentCulture); if (newArray.Length <= change.RowIndex) { Resize(ref newArray, change.RowIndex + 1); } newArray.SetValue(element, change.RowIndex); } changes.Add(new ChangeProperty.Property(property.Object, property.Name, newArray)); } // Apply all changes to the model in a single undoable command. SetPropertyValue(new ChangeProperty(changes)); // Update the value shown in the grid. This needs to happen after // we have applied changes to the model for obvious reasons. foreach (GridCellChangedArgs cell in args.ChangedCells) { // Add new rows to the view's grid if necessary. while (grid.RowCount <= cell.RowIndex + 1) { grid.RowCount++; } grid.DataSource.Rows[cell.RowIndex][cell.ColIndex] = GetCellValue(cell.RowIndex, cell.ColIndex); } // If the user deleted an entire row, do a full refresh of the // grid. Otherwise, only refresh read-only columns (PAWC). if (RemoveEmptyRows()) { PopulateGrid(model); } else { UpdateReadOnlyProperties(); } }
private void ToggleRender_Toggled(object sender, ToggledArgs r) { IGridCell where = GetCurrentCell; while (this.DataSource != null && where.RowIndex >= this.DataSource.Rows.Count) { this.DataSource.Rows.Add(this.DataSource.NewRow()); } this.DataSource.Rows[where.RowIndex][where.ColumnIndex] = !(bool)this.DataSource.Rows[where.RowIndex][where.ColumnIndex]; if (this.CellsChanged != null) { GridCellsChangedArgs args = new GridCellsChangedArgs(); args.ChangedCells = new List<IGridCell>(); args.ChangedCells.Add(this.GetCell(where.ColumnIndex, where.RowIndex)); this.CellsChanged(this, args); } }
private void ComboRender_Edited(object sender, EditedArgs e) { IGridCell where = GetCurrentCell; string newText = e.NewText; while (this.DataSource != null && where.RowIndex >= this.DataSource.Rows.Count) { this.DataSource.Rows.Add(this.DataSource.NewRow()); } // Put the new value into the table on the correct row. if (this.DataSource != null) { string oldtext = this.DataSource.Rows[where.RowIndex][where.ColumnIndex].ToString(); if (oldtext != newText) { try { this.DataSource.Rows[where.RowIndex][where.ColumnIndex] = newText; } catch (Exception) { } if (this.CellsChanged != null) { GridCellsChangedArgs args = new GridCellsChangedArgs(); args.ChangedCells = new List<IGridCell>(); args.ChangedCells.Add(this.GetCell(where.ColumnIndex, where.RowIndex)); this.CellsChanged(this, args); } } } }
/// <summary> /// User has changed the value of a cell. /// </summary> /// <param name="sender">Sender object.</param> /// <param name="e">Event arguments.</param> private void OnCellValueChanged2(object sender, GridCellsChangedArgs e) { // If all cells are being set to null, and the number of changed // cells is a multiple of the number of properties, we could be // deleting an entire row (or rows). In this case, we need // different logic, to resize all of the arrays. bool deletedRow = false; if (e.ChangedCells.All(c => c.NewValue == null) && e.ChangedCells.Count % 4 == 0) { // Get list of distinct rows which have been changed. int[] changedRows = e.ChangedCells.Select(c => c.RowIndex).Distinct().ToArray(); List <int> rowsToDelete = new List <int>(); foreach (int row in changedRows) { // Get columns which have been changed in this row. var changesInRow = e.ChangedCells.Where(c => c.RowIndex == row); int[] columns = changesInRow.Select(c => c.ColIndex).ToArray(); // If all non-readonly properties have been set to null in this row, // delete the row. bool deleteRow = true; for (int i = 0; i < 4; i++) { if (!columns.Contains(i)) { deleteRow = false; } } if (deleteRow) { // We can't delete the row now - what if the user has deleted // multiple rows at once (this is possible via shift-clicking). // We need one change property command per property. Otherwise, // only the last command will have an effect. deletedRow = true; rowsToDelete.Add(row); e.ChangedCells = e.ChangedCells.Where(c => c.RowIndex != row).ToList(); } } for (int i = 0; i < rowsToDelete.Count; i++) { int row = rowsToDelete[i]; table.Rows.RemoveAt(row); // Row numbers will change after deleting each row. rowsToDelete = rowsToDelete.Select(r => r > row ? r - 1 : r).ToList(); } } foreach (GridCellChangedArgs change in e.ChangedCells) { if (change.NewValue == change.OldValue) { continue; // silently fail } // If the user has entered data into a new row, we will need to // resize all of the array properties. CheckRowCount(change); object element = ReflectionUtilities.StringToObject(table.Columns[change.ColIndex].DataType, change.NewValue); table.Rows[change.RowIndex][change.ColIndex] = element; } // Apply all changes to the model in a single undoable command. explorerPresenter.CommandHistory.Add(new ChangeProperty(tableModel, "Tables", new List <DataTable>() { table })); // Update the value shown in the grid. This needs to happen after // we have applied changes to the model for obvious reasons. foreach (GridCellChangedArgs cell in e.ChangedCells) { // Add new rows to the view's grid if necessary. while (view.Grid2.RowCount <= cell.RowIndex + 1) { view.Grid2.RowCount++; } view.Grid2.DataSource.Rows[cell.RowIndex][cell.ColIndex] = table.Rows[cell.RowIndex][cell.ColIndex]; } // If the user deleted an entire row, do a full refresh of the // grid. Otherwise, only refresh read-only columns (PAWC). if (deletedRow) { view.Grid2.DataSource = table; } }
/// <summary> /// User has finished editing a cell. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void OnCellValueChanged(object sender, DataGridViewCellEventArgs e) { if (this.userEditingCell) { object oldValue = this.valueBeforeEdit; this.userEditingCell = false; // Make sure our table has enough rows. object newValue = this.Grid[e.ColumnIndex, e.RowIndex].Value; if (newValue == null) { newValue = DBNull.Value; } while (this.DataSource != null && e.RowIndex >= this.DataSource.Rows.Count) { this.DataSource.Rows.Add(this.DataSource.NewRow()); } // Put the new value into the table on the correct row. if (this.DataSource != null) { this.DataSource.Rows[e.RowIndex][e.ColumnIndex] = newValue; } if (this.valueBeforeEdit != null && this.valueBeforeEdit.GetType() == typeof(string) && newValue == null) { newValue = string.Empty; } if (this.CellsChanged != null && this.valueBeforeEdit != newValue) { GridCellsChangedArgs args = new GridCellsChangedArgs(); args.ChangedCells = new List<IGridCell>(); args.ChangedCells.Add(this.GetCell(e.ColumnIndex, e.RowIndex)); this.CellsChanged(this, args); } } }
/// <summary> /// User has finished editing a cell. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void OnCellValueChanged(object sender, EditedArgs e) { if (this.userEditingCell) { IGridCell where = GetCurrentCell; object oldValue = this.valueBeforeEdit; this.userEditingCell = false; // Make sure our table has enough rows. string newtext = e.NewText; object newValue = oldValue; if (newtext == null) { newValue = DBNull.Value; } Type dataType = oldValue.GetType(); if (dataType == typeof(string)) { newValue = newtext; } else if (dataType == typeof(double)) { double numval; if (Double.TryParse(newtext, out numval)) { newValue = numval; } else { newValue = Double.NaN; } } else if (dataType == typeof(Single)) { Single numval; if (Single.TryParse(newtext, out numval)) { newValue = numval; } else { newValue = Single.NaN; } } else if (dataType == typeof(int)) { int numval; if (int.TryParse(newtext, out numval)) { newValue = numval; } else { newValue = Single.NaN; } } else if (dataType == typeof(DateTime)) { DateTime dateval; if (DateTime.TryParse(newtext, out dateval)) { newValue = dateval; } } while (this.DataSource != null && where.RowIndex >= this.DataSource.Rows.Count) { this.DataSource.Rows.Add(this.DataSource.NewRow()); } // Put the new value into the table on the correct row. if (this.DataSource != null) { try { this.DataSource.Rows[where.RowIndex][where.ColumnIndex] = newValue; } catch (Exception) { } } if (this.valueBeforeEdit != null && this.valueBeforeEdit.GetType() == typeof(string) && newValue == null) { newValue = string.Empty; } if (this.CellsChanged != null && this.valueBeforeEdit != newValue) { GridCellsChangedArgs args = new GridCellsChangedArgs(); args.ChangedCells = new List <IGridCell>(); args.ChangedCells.Add(this.GetCell(where.ColumnIndex, where.RowIndex)); this.CellsChanged(this, args); } } }