with mostrar example data c# .net data-binding datagridview datatable

mostrar - fill datagridview with datatable c#



Custom DataGridViewCell no desencadena eventos de cambio de DataSource (1)

Finalmente pude resolver esto.

Resultó que el problema general no tenía nada que ver con mi IDataGridViewEditingCell personalizada. No recibir un evento RowChanged fue simplemente porque la fila DataGridView no se validó hasta que salí de la fila seleccionada actualmente , lo que no noté, porque solo había una fila en mis pruebas, así que tuve que enfocar un Control diferente para lograr esto. .

No validar la fila actual hasta que se desmarque / desenfoque parece ser un comportamiento normal y esperado en DataGridView. Aunque no era lo que quería, así que obtuve mi propio DataGridView e hice lo siguiente:

protected override void OnCellEndEdit(DataGridViewCellEventArgs e) { base.OnCellEndEdit(e); // Force validation after each cell edit, making sure that // all row changes are validated in the DataSource immediately. this.OnValidating(new System.ComponentModel.CancelEventArgs()); }

Hasta ahora, parece funcionar sin problemas, pero podría ser afortunado. Cualquier aprobación de un desarrollador de DataGridView con más experiencia sería muy apreciada, así que ... ¡siéntete libre de comentar!

Estoy teniendo problemas con WinForms DataGridView junto con el enlace de datos. Asigno un DataView que envuelve un DataSet al DataGridView.DataSource, que funciona perfectamente bien hasta el momento. El problema comienza cuando se implementa una DataGridViewCell personalizada . Mi objetivo es proporcionar un ComboBoxCell para seleccionar los valores de Enum que siempre es completamente interactivo y no requiere que el usuario ingrese al modo de edición de forma explícita.

aquí está la configuración de enlace:

  • DataSet S contiene exactamente una DataTable, T
  • DataView V envuelve dicha tabla
  • DataGridView.DataSource está configurado en V
  • Algunas partes de la aplicación se suscriben al evento T.RowChanged. Esta es la parte crucial.

En lo que respecta a la funcionalidad, mi celda personalizada se comporta exactamente como se esperaba. Sin embargo, no provoca la activación del evento DataTable.RowChanged a menos que todo el DataGridView pierda el foco ... pero todas las demás celdas no personalizadas lo hagan. Sigo recibiendo un evento CellValueChanged, y el DataSet tiene el nuevo valor ... pero no hay ni DataTable.RowChanged ni DataGridView.DataBindingComplete, y la fila no se invalida automáticamente como suele hacerlo.

Obviamente estoy haciendo algo mal. Probablemente me esté perdiendo un evento notificador o haya implementado algo incorrecto, pero después de dos días de buscar, pisar y desensamblar el código .Net todavía estoy completamente atascado.

Estas son las secciones más importantes (no el código fuente completo) de la definición de clase:

public class DataGridViewEnumCell : DataGridViewCell, IDataGridViewEditingCell { private Type enumType = null; private Enum enumValue = default(Enum); private bool enumValueChanged = false; public virtual object EditingCellFormattedValue { get { return this.GetEditingCellFormattedValue(DataGridViewDataErrorContexts.Formatting); } set { this.enumValue = (Enum)Utility.SafeCast(value, this.enumType); } } public virtual bool EditingCellValueChanged { get { return this.enumValueChanged; } set { this.enumValueChanged = value; } } public override Type EditType { get { return null; } } public override Type FormattedValueType { get { return this.enumType; } } public override Type ValueType { get { if (this.OwningColumn != null && this.OwningColumn.ValueType != null) { return this.OwningColumn.ValueType; } else { return this.enumType; } } set { base.ValueType = value; } } // The kind of Enum that is edited in this cell. public Type EnumValueType { get { return this.enumType; } set { this.enumType = value; } } public virtual object GetEditingCellFormattedValue(DataGridViewDataErrorContexts context) { if (context.HasFlag(DataGridViewDataErrorContexts.ClipboardContent)) { return Convert.ToString(this.enumValue); } else { return this.enumValue ?? this.enumType.GetDefaultValue(); } } public override object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter) { // Cast the Enum value to the original cell value type object cellVal; Utility.SafeCast(formattedValue, this.ValueType, out cellVal); return cellVal; } protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) { if (this.DataGridView == null || value == null) { return this.enumType.GetDefaultValue(); } // Cast the cell value to the appropriate Enum value type object enumVal; Utility.SafeCast(value, this.enumType, out enumVal); // Let the base implementation apply additional formatting return base.GetFormattedValue(enumVal, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context); } private Enum GetCurrentValue() { object unknownVal = (this.enumValueChanged ? this.enumValue : this.Value); object enumVal; Utility.SafeCast(unknownVal, this.enumType, out enumVal); return (Enum)enumVal; } public virtual void PrepareEditingCellForEdit(bool selectAll) { this.enumValue = this.GetCurrentValue(); } protected override void OnClick(DataGridViewCellEventArgs e) { base.OnClick(e); if (this.DataGridView.CurrentCell == this && (DateTime.Now - this.mouseClosed).TotalMilliseconds > 200) { // Due to some reason I don''t understand sometimes EditMode is already active. // Don''t do it twice in these cases. if (!this.IsInEditMode) { // Begin editing this.DataGridView.BeginEdit(true); } this.ShowDropDown(); } } public void HideDropDown() { // ... snip ... // Revert value to original state, if not accepted explicitly // It will also run into this code after the new selection // has been accepted (see below) if (this.DataGridView != null) { this.enumValue = this.GetCurrentValue(); this.enumValueChanged = false; this.DataGridView.EndEdit(); } } // Called when a value has been selected. All calue changes run through this method! private void dropdown_AcceptSelection(object sender, EventArgs e) { Enum selectedEnum = (Enum)this.dropdown.SelectedItem; if (!this.enumValue.Equals(selectedEnum)) { this.enumValue = selectedEnum; this.enumValueChanged = true; this.DataGridView.NotifyCurrentCellDirty(true); this.DataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit); } } }

Una vez más, DataSource está activando eventos correctamente cuando DataGridView pierde el foco, o cuando edita cualquier otra celda en DataGridView, pero de alguna manera no logro actualizarlo después de editar mi celda personalizada.

¿Cómo puedo conseguir esto?