Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save PedroAvila/b4336f45ed084b03e281b550140b871e to your computer and use it in GitHub Desktop.
Save PedroAvila/b4336f45ed084b03e281b550140b871e to your computer and use it in GitHub Desktop.
Mi DataGridView para trasladarme entre celdas de una misma fila y al llegar al final me cree la siguiente fila
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
Copy link

webJose commented Jul 21, 2018

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.

@PedroAvila
Copy link
Author

PedroAvila commented Jul 26, 2018

@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();
                        }
                    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment