winforms 如何在DataGridView中显示DateTimePicker?

hs1rzwqc  于 2022-11-25  发布在  其他
关注(0)|答案(7)|浏览(199)

是否有方法将DateTimePicker控件放入DataGridView中?
我检查了所有可能的属性,但它给予复选框,组合框等选项,但不是日期时间选择器。

8nuwlpux

8nuwlpux1#

您没有遗漏任何内置选项,但是可以同时创建DataGridViewColumnDataGridViewCell类的子类来承载您选择的任何控件。
MSDN上的这篇文章更详细地解释了这个过程,甚至包括一些示例代码:
How to: Host Controls in Windows Forms DataGridView Cells
您也可以在Code Project上找到完整的范例:Generic DataGridView V2.0

enxuqcxy

enxuqcxy2#

一种策略是:
1.在选定单元格获得焦点时在其顶部绘制一个DateTimePicker
1.用单元格的值水合dtp
1.当dtp的值更改时,将其镜像回单元格的值
1.并在单元格失去焦点时隐藏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具有焦点时,此方法当前不处理键盘事件,并且在窗体四处移动时也不处理调整大小或重画

ppcbkaq5

ppcbkaq53#

也许这是不正确的,但简单的技巧和相同的结果.........少了很多代码......我只是玩玩,虽然在盒子外面,只是设置
我隐藏我的直到他们点击单元格,或者你可以显示第一我宣布:

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

超级基本型,我直接把它放在盒子里,看起来没有什么不合适的
或者超级简单模式.......我只是喜欢隐藏我的,直到列点击

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

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

wd2eg0qa

wd2eg0qa4#

好的......使用一些@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
nkhmeac6

nkhmeac65#

若要解决在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);

    }
rjjhvcjd

rjjhvcjd6#

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

vh0rcniy

vh0rcniy7#

使用如下所示的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);

                }
        }
    }

enter image description here

相关问题