I am displaying a Panel
that contains a small DataGridView
in it, when clicking on the cell of another DataGridView
.
I've managed to do it, by getting the coordinate of each cell where I want to display the panel, and I've calculated where it should be displayed, but I've basically done it by brute force.
When I say that it does not exceed the limits, I mean that if I click on some corner of the end of DataGridView
the panel, it is displayed correctly in a position that does not exceed the full size of the panel.DataGridView
private void dgrid_planificacion_CellClick(object sender, DataGridViewCellEventArgs e)
{
//Obetengo las coordenadas de la celda seleccionada.
Rectangle coordenada = dgrid_planificacion.GetCellDisplayRectangle(dgrid_planificacion.CurrentCell.ColumnIndex, dgrid_planificacion.CurrentCell.RowIndex, false);
if (e.ColumnIndex > 1)
{
int ancho_grid, alto_grid, ancho_panel, alto_panel, ancho_celda, alto_celda;
ancho_grid = dgrid_planificacion.Size.Width;
alto_grid = dgrid_planificacion.Size.Height;
ancho_panel = panel_detalle.Size.Width;
alto_panel = panel_detalle.Size.Height;
ancho_celda = coordenada.Location.X;
alto_celda = coordenada.Location.Y;
if (!Convert.ToString(dgrid_planificacion.CurrentRow.Cells[0].Value).Equals(""))
{
//Ezquina superior izquierda.
if (( alto_panel + alto_celda ) < ( alto_grid ) && ( ancho_panel + ancho_celda ) < ancho_grid)
{
//El numero 14 es para indicarle la posicion que tendra el panel en el eje Y (comienzo de la celda)
panel_detalle.Location = new Point(( ancho_celda + dgrid_planificacion.Location.X ),
( alto_celda + dgrid_planificacion.Location.Y ) + 14);
panel_detalle.BringToFront(); //Para que el panel este por arriba del DatagridView Planificacion
panel_detalle.Visible = true;
}
else
//Esquina Superior Derecha
if (( alto_panel + alto_celda ) < ( alto_grid ))
{
//El numero 2 es para controlar la sepacion del panel de la celda.
panel_detalle.Location = new Point(( ancho_celda - ancho_panel ) + 33,
( coordenada.Bottom ) - 2);
panel_detalle.BringToFront();
panel_detalle.Visible = true;
}
else
//Esquina Inferior Izquierda
if (( coordenada.Bottom + alto_panel ) > ( alto_grid ) && ( ancho_panel + ancho_celda ) < ( ancho_grid ))
{
panel_detalle.Location = new Point(( ancho_celda + dgrid_planificacion.Location.X ),
( alto_celda - alto_panel ) + 1);
panel_detalle.BringToFront();
panel_detalle.Visible = true;
}
else //Esquina Inferior Derecha
{
//El numero 33 indicar el comienzo de la celda y mostrar el panel en esa posicion.
panel_detalle.Location = new Point(( ancho_celda - ancho_panel ) + 33,
( alto_celda - alto_panel ));
panel_detalle.BringToFront();
panel_detalle.Visible = true;
}
}
else
panel_detalle.Visible = false;
}
}
How can I optimize this code? so that I don't have to use fixed values in the code, since if at some point I give it another application I would have to calculate the fixed values again, if I have more or fewer columns, etc.
Note: Since there is no nesting in C# by default DataGridView
, I have chosen to do it this way, I know there are external controls that contain a Master DataGridView
with many features, but I don't want to use one for now.
The solution that I offer you has certain restrictions about the positioning of your DataGridview where it should be adjusted as much as possible to the beginning 0,0 of your Form. If, due to necessity, you cannot do it this way, then you will have to handle two extra variables as a fix to calculate exactly the position of each cell, since if you noticed, the one returned is in relation to the Datagridview and not the Form.
Solution