Posteriormente a consultar con expertos en el tema, programadores de diversas ramas y maestros dimos con la respuesta a la interrogande y la dejamos plasmada en este post.
Solución:
No se ha perdido ninguna opción integrada, pero es posible subclasificar tanto el DataGridViewColumn
y DataGridViewCell
clases para albergar cualquier control de su elección.
Este artículo en MSDN explica el proceso con más detalle e incluso incluye código de muestra:
Cómo: alojar controles en celdas DataGridView de Windows Forms
También puede encontrar una muestra completa en Code Project: Generic DataGridView V2.0
Una estrategia sería:
- pintar un
DateTimePicker
encima de la celda seleccionada cuando recibe el foco - hidratar el dtp con los valores de la celda
- cuando el valor del dtp cambie, reflejelo nuevamente en el valor de la celda
- y ocultar el dtp cuando la celda pierde el foco
Aquí hay una manera de manejar los eventos de la cuadrícula con la estrategia presentada:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
// determine if click was on our date column
if (dataGridView1.Columns[e.ColumnIndex].DataPropertyName == nameof(User.BirthDate))
// initialize DateTimePicker
dtp = new DateTimePicker();
dtp.Format = DateTimePickerFormat.Short;
dtp.Visible = true;
dtp.Value = DateTime.Parse(dataGridView1.CurrentCell.Value.ToString());
// set size and location
var rect = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
dtp.Size = new Size(rect.Width, rect.Height);
dtp.Location = new Point(rect.X, rect.Y);
// attach events
dtp.CloseUp += new EventHandler(dtp_CloseUp);
dtp.TextChanged += new EventHandler(dtp_OnTextChange);
dataGridView1.Controls.Add(dtp);
// on text change of dtp, assign back to cell
private void dtp_OnTextChange(object sender, EventArgs e)
dataGridView1.CurrentCell.Value = dtp.Text.ToString();
// on close of cell, hide dtp
void dtp_CloseUp(object sender, EventArgs e)
dtp.Visible = false;
Y aquí hay una configuración básica para un formulario que tiene un DataGridView agregado.
private void Form1_Load(object sender, EventArgs e)
// add columns
var nameCol = new DataGridViewTextBoxColumn()DataPropertyName = nameof(User.Name),HeaderText = "Name";
var dateCol = new DataGridViewTextBoxColumn()DataPropertyName = nameof(User.BirthDate),HeaderText = "Birthday";
dataGridView1.Columns.AddRange(nameCol, dateCol);
// add data source
var users = new List()
new User() Name = "Briana", BirthDate = new DateTime(2019,10,10),
new User() Name = "Grace", BirthDate = new DateTime(2018,1,18)
;
dataGridView1.DataSource = users;
private DateTimePicker dtp get; set;
private class User
public string Name get; set;
public DateTime BirthDate get; set;
Nota: este enfoque actualmente no maneja los eventos del teclado cuando el dtp tiene el foco y tampoco maneja el cambio de tamaño o el repintado si el formulario se mueve
Tal vez esto no sea correcto, pero es un truco fácil y el mismo resultado… mucho menos código… Solo estaba jugando y aunque fuera de la caja, solo configuré
Oculto el mío hasta que hacen clic en la celda, o puedes mostrar Primero declaré:
DateTimePicker1.Visible = False
cuando haga clic en la celda, ejecute este código…
DateTimePicker1.Visible = True
ActiveControl = DateTimePicker1
Luego abajo
Public Sub DateTimePicker1_ValueChanged(sender As System.Object, e As System.EventArgs) Handles DateTimePicker1.ValueChanged
requestDGV.Rows(0).Cells("requestTimeOff").Value = (DateTimePicker1.Value)
DateTimePicker1.Visible = False
DateTimePicker1.Enabled = False
End Sub
Super Basic, y lo tengo colocado directamente en la caja, no se ve fuera de lugar
O el modo súper fácil……. Solo me gusta ocultar el mío hasta que haga clic en la columna
Public Sub DateTimePicker1_ValueChanged(sender As System.Object, e As System.EventArgs) Handles DateTimePicker1.ValueChanged
requestDGV.Rows(0).Cells("requestTimeOff").Value = (DateTimePicker1.Value)
End Sub
Realmente solo necesitas esa línea… los datos estarán en la cuadrícula, solo mucho menos código…
valoraciones y reseñas
Ten en cuenta difundir este ensayo si te fue útil.