如何在 DataGridView 中显示 DateTimePicker?

发布于 2024-10-14 10:12:13 字数 110 浏览 8 评论 0原文

有什么方法可以将 DateTimePicker 控件放入 DataGridView 中吗?

我检查了所有可能的属性,但它提供了复选框、组合框等选项,但没有提供 DateTimePicker。

Is there any way to put a DateTimePicker control in the DataGridView?

I checked all the possible properties but it give option of checkbox, combo box etc, but not the DateTimePicker.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

最舍不得你 2024-10-21 10:12:13

您没有错过任何内置选项,但可以对 DataGridViewColumnDataGridViewCell 类进行子类化以托管您选择的任何控件。

MSDN 上的这篇文章更详细地解释了该过程,甚至包括一些示例代码:
如何:在 Windows 窗体 DataGridView 单元格中托管控件

您还可以在代码项目上找到完整的示例: 通用 DataGridView V2.0

You haven't missed any built-in option, but it is possible to subclass both the DataGridViewColumn and DataGridViewCell classes to host any control of your choosing.

This article on MSDN explains the process in more detail, and even includes some sample code:
How to: Host Controls in Windows Forms DataGridView Cells

You can also find a complete sample on Code Project: Generic DataGridView V2.0

甜味超标? 2024-10-21 10:12:13

一种策略是:

  1. 当选定的单元格接收焦点时,在其顶部绘制一个 DateTimePicker
  2. 当 dtp 的值发生变化时,将 dtp 与单元格的值进行水合
  3. ,将其镜像回单元格的值
  4. 并隐藏 dtp当单元格失去焦点时

这是一种使用布局策略处理网格事件的方法:

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
        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;
}

这是添加了 DataGridView 的表单的基本设置

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

注意:当 dtp 具有焦点时,此方法当前不处理键盘事件,并且在表单移动时也不处理调整大小或重新绘制

One strategy would be:

  1. to paint a DateTimePicker on top of the selected cell when it receives focus
  2. hydrate the dtp with the cell's values
  3. when the dtp's value changes, mirror it back into the cell's value
  4. and hide the dtp when the cell loses focus

Here's a way to handle grid events with the laid out strategy:

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
        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;
}

And Here's a basic setup for a form that has a DataGridView added to it

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

Note: This approach does not currently handle keyboard events when the dtp has focus and also does not handle resizing or repainting if the form moves around

短暂陪伴 2024-10-21 10:12:13

也许这不合适,但简单的技巧和相同的结果......更少的代码......我只是在玩,虽然在盒子外面,只需设置

我隐藏我的直到他们单击单元格,或者你可以显示
首先我声明:

DateTimePicker1.Visible = False

当您单击单元格时,运行此代码...

    DateTimePicker1.Visible = True
    ActiveControl = DateTimePicker1

然后在

 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 下方,我将它直接放在框中,看起来不合适

或超级简单模式......我就像隐藏我的直到列单击

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

你真的只需要一行......数据将在网格中,只是少了很多代码......

Maybe this isn't proper, but easy trick and same result........ lot less code......I was just playing around and though outside the box, just set

I hide mine until they click cell, or you can show
First I declared :

DateTimePicker1.Visible = False

when you click in cell, run this code...

    DateTimePicker1.Visible = True
    ActiveControl = DateTimePicker1

Then below

 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 , and i have it sitting directly in the box, doesn't look out of place

Or super easy mode.......I just like to hide mine till column click

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

You really just need that one line.....data will be in the grid, just a lot less code.....

千紇 2024-10-21 10:12:13

好的...使用一些 @rajat 和 @Aaron 示例,我制作了一个在 DateTimePicker 单元格上弹出的示例。谢谢大家。

Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick

    If e.ColumnIndex = 8 Then 'CHECK IF IT IS THE RIGHT COLUMN

        'SET SIZE AND LOCATION
        Dim rect = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True)
        DateTimePicker1.Size = New Size(rect.Width, rect.Height)
        DateTimePicker1.Location = New Point(rect.X + 10, rect.Y + 76) 'USE YOU OFFSET HERE

        DateTimePicker1.Visible = True
        ActiveControl = DateTimePicker1

    End If

End Sub


Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged

    If DataGridView1.RowCount > 0 Then 'JUST TO AVOID FORM LOAD CRASH

        DataGridView1.CurrentCell.Value = DateTimePicker1.Value.ToShortDateString
        DateTimePicker1.Visible = False

    End If

Ok... Using some of @rajat and @Aaron examples, i made one that pops up on the DateTimePicker cell. Thanks everyone.

Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick

    If e.ColumnIndex = 8 Then 'CHECK IF IT IS THE RIGHT COLUMN

        'SET SIZE AND LOCATION
        Dim rect = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True)
        DateTimePicker1.Size = New Size(rect.Width, rect.Height)
        DateTimePicker1.Location = New Point(rect.X + 10, rect.Y + 76) 'USE YOU OFFSET HERE

        DateTimePicker1.Visible = True
        ActiveControl = DateTimePicker1

    End If

End Sub


Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged

    If DataGridView1.RowCount > 0 Then 'JUST TO AVOID FORM LOAD CRASH

        DataGridView1.CurrentCell.Value = DateTimePicker1.Value.ToShortDateString
        DateTimePicker1.Visible = False

    End If
痴意少年 2024-10-21 10:12:13

要解决在 DataGridView 中使用 DateTimePicker 时的一些输入问题,您需要将以下内容添加到上面引用的 Microsoft 示例中。我花了相当长的时间才找到 valuechanged 事件未按预期触发的问题。修复来自这里(stackoverflow)并在下面翻译成 C#。在此处添加此信息似乎很合适,因为我在 DataGridView 和 DateTimePicker 上搜索时不断找到此论坛帖子。

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {

        switch (keyData & Keys.KeyCode)
        {
            case Keys.Enter:
            case Keys.Tab:
                this.dataGridView.Focus();
                break; 
        }

        return base.ProcessCmdKey(ref msg, keyData);

    }

To solve some entry issues when using the DateTimePicker in a DataGridView you will want to add the following to the Microsoft Sample referenced above. It took quite a while to search out the problems with the valuechanged event not firing as expected. The fix came from here (stackoverflow) and translated to C# below. It seemed appropriate to add this information here as I keep finding this forum post when searching on DataGridView and DateTimePicker.

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {

        switch (keyData & Keys.KeyCode)
        {
            case Keys.Enter:
            case Keys.Tab:
                this.dataGridView.Focus();
                break; 
        }

        return base.ProcessCmdKey(ref msg, keyData);

    }
长发绾君心 2024-10-21 10:12:13

使用 RowsAdded 事件,如下所示 -

 private void dgvEducationalData_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
    {
        DataGridViewRow row = dgvEducationalData.Rows[e.RowIndex];
        Console.WriteLine("Rows added");
        if (e.RowIndex != -1)
        {
            foreach (DataGridViewCell cell in row.Cells)
                if (cell.ColumnIndex == 2 || cell.ColumnIndex == 1)
                {

                    dateTimePicker = new DateTimePicker();
                    dateTimePicker.Font = new Font("Segoe UI", 10);
                    dgvEducationalData.Controls.Add(dateTimePicker);
                    dateTimePicker.Format = DateTimePickerFormat.Short;
                    Rectangle oRectangle = dgvEducationalData.GetCellDisplayRectangle(cell.ColumnIndex, e.RowIndex, true);
                    dateTimePicker.Size = new Size(oRectangle.Width - 2, oRectangle.Height - 10);
                    dateTimePicker.Location = new Point(oRectangle.X, oRectangle.Y);

                }
        }
    }

在此处输入图像描述

Use RowsAdded Event shown as below-

 private void dgvEducationalData_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
    {
        DataGridViewRow row = dgvEducationalData.Rows[e.RowIndex];
        Console.WriteLine("Rows added");
        if (e.RowIndex != -1)
        {
            foreach (DataGridViewCell cell in row.Cells)
                if (cell.ColumnIndex == 2 || cell.ColumnIndex == 1)
                {

                    dateTimePicker = new DateTimePicker();
                    dateTimePicker.Font = new Font("Segoe UI", 10);
                    dgvEducationalData.Controls.Add(dateTimePicker);
                    dateTimePicker.Format = DateTimePickerFormat.Short;
                    Rectangle oRectangle = dgvEducationalData.GetCellDisplayRectangle(cell.ColumnIndex, e.RowIndex, true);
                    dateTimePicker.Size = new Size(oRectangle.Width - 2, oRectangle.Height - 10);
                    dateTimePicker.Location = new Point(oRectangle.X, oRectangle.Y);

                }
        }
    }

enter image description here

夜访吸血鬼 2024-10-21 10:12:13

我认为 DateTimePicker 上的 CloseUp 事件更合适,因为更改的值会在任何更改时触发,而 CloseUp 仅在选择整个日期时触发

I think the CloseUp event on DateTimePicker is more appropriate because the changed value is triggering on any change while CloseUp only triggers when the entire date is selected

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文