-
-
Save PedroAvila/b4336f45ed084b03e281b550140b871e to your computer and use it in GitHub Desktop.
| public class RequestNewRowEventArgs : EventArgs | |
| { | |
| #region Properties | |
| public bool RowAdded { get; set; } | |
| public bool Handled { get; set; } | |
| #endregion | |
| } | |
| public delegate void RequestNewRowEventHandler(object sender, RequestNewRowEventArgs e); | |
| public class MiDataGridView : DataGridViewX | |
| { | |
| public event RequestNewRowEventHandler RequestNewRow; | |
| protected void RaiseRequestNewRow(RequestNewRowEventArgs e) | |
| { | |
| RequestNewRow?.Invoke(this, e); | |
| } | |
| protected override void OnKeyDown(KeyEventArgs e) | |
| { | |
| if (e.KeyCode == Keys.Enter) | |
| { | |
| SendKeys.Send("{TAB}"); | |
| e.Handled = true; | |
| return; | |
| } | |
| base.OnKeyDown(e); | |
| } | |
| protected override bool ProcessDialogKey(Keys keyData) | |
| { | |
| Keys k = keyData & Keys.KeyCode; | |
| if (k == Keys.Tab) | |
| { | |
| Debug.Print("Se ha presionado la tecla TAB."); | |
| //Obtener la posición actual. | |
| int r = CurrentCell.RowIndex; | |
| int c = CurrentCell.ColumnIndex; | |
| bool isNewRow = CurrentRow.IsNewRow; | |
| Debug.Print("Fila: {0}, columna: {1}, es nueva: {2}", r, c, isNewRow); | |
| /* | |
| * Las reglas: | |
| * 1. Si todas las columnas son de lectura, no implementar esta lógica. | |
| * 2. Si hay columnas de escritura en la fila actual a la derecha de la celda | |
| * actual, moverse a la siguiente columna de escritura de esta fila. | |
| * 3. Si no hay columnas de escritura en la fila actual a la derecha de la celda | |
| * actual, moverse a la fila siguiente, primera columna de escritura. | |
| */ | |
| bool allReadOnly = true; | |
| foreach (DataGridViewColumn col in Columns) | |
| { | |
| if (!col.ReadOnly) | |
| { | |
| allReadOnly = false; | |
| break; | |
| } | |
| } | |
| if (allReadOnly) | |
| { | |
| //Regla 1. | |
| return base.ProcessDialogKey(keyData); | |
| } | |
| //Buscar la siguiente columna que no sea de sólo lectura. | |
| while (c < Columns.Count - 1 && Columns[c + 1].ReadOnly) | |
| { | |
| ++c; | |
| } | |
| if (c >= Columns.Count - 1) | |
| { | |
| //Regla 2. | |
| if (++r == Rows.Count) | |
| { | |
| RequestNewRowEventArgs e = new RequestNewRowEventArgs() | |
| { | |
| Handled = false, | |
| RowAdded = false | |
| }; | |
| RaiseRequestNewRow(e); | |
| if ((e.Handled && !e.RowAdded) || (!e.Handled && !AllowUserToAddRows)) | |
| { | |
| return base.ProcessDialogKey(keyData); | |
| } | |
| else if (!e.Handled && AllowUserToAddRows) | |
| { | |
| Rows.Add(); | |
| } | |
| } | |
| c = 0; | |
| while (Columns[c + 1].ReadOnly) | |
| { | |
| ++c; | |
| } | |
| } | |
| else | |
| { | |
| //Regla 3. Nada más que hacer. | |
| } | |
| CurrentCell = Rows[r].Cells[c]; | |
| return true; | |
| } | |
| else | |
| { | |
| return base.ProcessDialogKey(keyData); | |
| } | |
| } | |
| } |
@webJose, el formulario donde implemento el control personalizado DGV tengo la propiedad del form KeyPreview = true por que en la cabecera(un GroupBox) donde tengo unos controles me desplazo entre ellos presionando la tecla [ENTER] cuando esta en true la propiedad que te menciono solo puedo desplazarme con la tecla [TAB] y no con [ENTER] en el DGV, pero si KeyPreview = false ahí si puedo desplazarme en la fila entre sus columnas con [TAB] y [ENTER] creo esto sería lo ideal, pero perdería la funcionalidad de desplazarme entre controles con la tecla [ENTER] tampoco estaría mal desplazarme solo con [TAB] en el DGV ¿como debería de manejar de la mejor manera ese problema?.
He estado depurando el control personalizado y en el siguiente fragmento de código nunca entra a la condición else if, ¿que debería de suceder para que entre a la codición?
//Regla 2.
if (++r == Rows.Count)
{
RequestNewRowEventArgs e = new RequestNewRowEventArgs()
{
Handled = false,
RowAdded = false
};
RaiseRequestNewRow(e);
if ((e.Handled && !e.RowAdded) || (!e.Handled && !AllowUserToAddRows))
{
return base.ProcessDialogKey(keyData);
}
else if (!e.Handled && AllowUserToAddRows)
{
Rows.Add();
}
}
La única diferencia entre ambos es que si lo hace en el código del DGV, entonces ya no tiene que hacerlo en ninguna otra parte, y si usa este DGV personalizado en múltiples formularios ya no tendrá que personalizarlo múltiples veces. Supongo que entonces se lo dejo a decisión suya.