如何将 UserControl 添加到 VB.net 中的 DataGridView 并使控件始终显示?

How to add a UserControl to a DataGridView in VB.net, and have the control always showing?

我制作了一个用户控件,它基本上是一个面板,上面有一堆标签、按钮和事件处理程序。我希望能够使用这些控件填充 DataGridView。

我已按照 this MSDN article 中的说明进行操作,并创建了一个 DataGridViewColumn 和一个 DataGridViewCell class 以与我的控件关联。

我遇到的问题是控件未呈现。当我 运行 上面 link 处的代码时,它在单元格中显示日期,而用户控件仅在单元格被编辑时显示。我希望发生的是控件在单元格中始终可见,类似于 DataGridViewImageColumn 中的行为。

如何强制 DataGridView 始终显示控件?

主要思想:

  1. 创建用户控件
  2. 在表单加载事件中,为每条记录创建一个用户控件实例,为其属性设置值,添加事件处理程序,将其可见性设置为 false,然后将其添加到您的网格控件集合中,并设置标签将您想要的单元格或该行添加到此控件。
  3. 处理DataGridView的CellPainting event of your grid and for each row of grid, retrieve tag of your wanted cell and convert it to your control and position it in cell bounds and make it visible. To get the position that control should be shown use GetCellDisplayRectangle方法

截图:

我的示例控件名为 SomeControl,包含一个标签和一个文本框以及一个 属性 SomeProperty 和一个事件 SomePropertyChanges。我在自定义控件的文本框中显示单元格值。

您可以使用包含任何控件以及任何类型的属性和事件的自定义控件执行任何操作。

代码:

这是类似于vb的伪代码

'This is not VB, this is vb-like pseudo code 
Private Sub Form_Load(sender as object , e as EventArgs)
    'Get data
    'Show data in grid

    'For each row
    For Each row as DataGridViewRow in this.categoryDataGridView.Rows
        'Create an instance of control
        Dim myControl as New SomeControl()

        'Set properties and register event handlers
        myControl.SomeProperty = row.Cells[2].Value
        myControl.SomePropertyChanged += myControl_SomePropertyChanged

        'Make it invisible
        myControl.Visible = False

        'Set tag of your wanted cell to control
        row.Cells[2].Tag = myControl

        'Add control to Controls collection of grid
        this.categoryDataGridView.Controls.Add(myControl)
    Next
End Sub

Private Sub myControl_SomePropertyChanged(sender as object, e as EventArgs)

    'event handler of SomePropertyChanged for custom control
    'do stuff here
End Sub

Private Sub dataGridView_CellPainting(sender as object, e as DataGridViewCellPaintingEventArgs )
    'for each row
    For i as Integer=0 To dataGridView.RowCount- 1
        'Extract control from tag of your wanted cell
        var myControl= this.dataGridView.Rows[i].Cells[2].Tag as SomeControl

        'Get cell rectangle
        Dim cellRectangle As Rectangle= dataGridView.GetCellDisplayRectangle(2, i, True)

        'Set location
        myControl.Location = New Point(cellRectangle.X, cellRectangle.Y )

        'Set size
        myControl.Size = New Size(cellRectangle.Width - 1, cellRectangle.Height - 1)

        'Make visible
        myControl.Visible = True
    Next
}

阅读这篇文章 如何将自定义用户控件添加到数据网格视图? http://bytes.com/topic/visual-basic-net/answers/444528-how-can-you-add-custom-user-control-datagridview

private void button1_Click(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();

        dt.Columns.Add("Name");
        dt.Columns.Add("Email Id");
        for (int j = 0; j < 10; j++)
        {

            dt.Rows.Add("", "ravindra.m089@gmail.com");

        }

        this.dataGridView1.DataSource = dt;

        this.dataGridView1.Columns[0].Width = 200;



        /*

         * First method : Convert to an existed cell type such ComboBox cell,etc

         */



        DataGridViewComboBoxCell ComboBoxCell = new DataGridViewComboBoxCell();

        ComboBoxCell.Items.AddRange(new string[] { "aaa", "bbb", "ccc" });

        this.dataGridView1[0, 0] = ComboBoxCell;

        this.dataGridView1[0, 0].Value = "bbb";



        DataGridViewTextBoxCell TextBoxCell = new DataGridViewTextBoxCell();

        this.dataGridView1[0, 1] = TextBoxCell;

        this.dataGridView1[0, 1].Value = "some text";



        DataGridViewCheckBoxCell CheckBoxCell = new DataGridViewCheckBoxCell();

        CheckBoxCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;

        this.dataGridView1[0, 2] = CheckBoxCell;

        this.dataGridView1[0, 2].Value = true;


        DataGridViewTextBoxCell txt = new DataGridViewTextBoxCell();
        txt.ToolTipText = "Enter Ur Name";
        this.dataGridView1[0, 3] = txt;
        this.dataGridView1[0, 3].Value = "lakshman";


        /*

         * Second method : Add control to the host in the cell

         */

        DateTimePicker dtp = new DateTimePicker();

        dtp.Value = DateTime.Now.AddDays(-10);

        //add DateTimePicker into the control collection of the DataGridView

        this.dataGridView1.Controls.Add(dtp);

        //set its location and size to fit the cell

        dtp.Location = this.dataGridView1.GetCellDisplayRectangle(0, 3, true).Location;

        dtp.Size = this.dataGridView1.GetCellDisplayRectangle(0, 3, true).Size;

        TextBox Text = new TextBox();
        Text.Text = "This my Name";
        Text.BackColor = Color.RosyBrown;
        this.dataGridView1.Controls.Add(Text);
        Text.Location = this.dataGridView1.GetCellDisplayRectangle(0, 4, true).Location;
        Text.Size = this.dataGridView1.GetCellDisplayRectangle(0, 4, true).Size; 
    }