-
-
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); | |
} | |
} | |
} |
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.
@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();
}
}
En este fragmento de código.
Podría poner código para que entre en edición la primera celda de la primera columna o mejor ya sería en el evento RowsAdded del control personalizado como: