[SOLVED] How do I add a custom control to a data grid view

Answered
1
0

I have tried to work out how to add a custom column to a data grid view

It seems to have something to do with setting the control as the custom control

dgvOfficeStaff.Columns[0].CellTemplate.Control = mccStaff;

You then seem to need to have to add the control to each Cell;

private void dgvOfficeStaff_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 0 && dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Value != null)
{
if(dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Control == null) dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Control = mccStaff;
((MultiColumnComboBox)dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Control).BoundValue = dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Value;
}
}

However this code does not work.

What is the correct way to add a custom control column?

Thanks for your help

Ewan

  • You must to post comments
Good Answer
0
0

See attached sample. It has 2 column classes, one is the revised DataGridViewProgressBarColumn which now has a TrackBar editor. In this case,  since the TrackBar doesn’t use the Text property for the value, it implements the IDataGridViewEditingControl. The second column is a DataGridViewUpDownColumn using a custom NumericUpDown control to edit the value.

The DataGridViewColumn.Editor is not visible in the designer – you need to set it in code.

  • Luca (ITG)
    While doing this exercise I noticed that IDataGridViewEditingControl returns string for GetEditingControlFormattedValue when it should return object. We may change this in the future.
  • You must to post comments
0
0

Cracked it in the end. The control stays bound to the cell now.

However performance is really slow if when loading a single row table multicolumn (not filtered) for each cell and using a header click to load the full multi column box.

The slowness is just simply loading the grid and scrolling not actually editing. The multicolumn table replace on edit is fast.

  • You must to post comments
0
0

Thanks for the sample Luca

How do I populate the Data Grid View Correctly as I need at least one row in the Multicolumn Combo Box for each row, to obtain the initial display value.

The issue with the sort is the control is being reset in my code and I don’t understand why, the code below is called which does not happen in your sample.

Tests show that the Control is already Null when this code is called

public DataGridViewMultiComboBoxColumnCell()
{
this.Control = new MultiColumnComboBox()
{
Border = BorderStyle.None,
Dock = DockStyle.Fill
};
}

Thanks for your help

Ewan

  • You must to post comments
0
0

Screenshot

Attachment
  • You must to post comments
0
0

Hi Luca

Just to be clear if I use a Column Editor which I cannot find in the designer or Wise J 2 tools.

So where do I pick it up from?

When the Data Grid View is loaded will it look like the attached, given the actual values in the data grid view are payroll numbers?

(From what you say it appears using my current approach that the cell data source is being lost on sort which explains why all the cells revert back to payroll numbers.

If I click on a drop down no data is present)

Thanks for your help

Ewan

Attachment
  • You must to post comments
0
0

Hi Luca

Could you post a code snippit that demonstrates how to use the column editor property to assign a multicolumn combo box to a column and populate its data source.

Thanks for your help

Ewan

  • Luca (ITG)
    dataGridColumn1.Editor = this.editor1; You can create the editor in the designer and assign it, or create it programmatically, It’s just an instance that is reused when editing the cells. Like the built in cell editors, It’s the same functionality. In one case it uses default instances like Wisej.Web.TextBox, in the other it uses the instance you provide.
  • You must to post comments
0
0

I cannot reproduce. The cell control is bound to the correct cell also after sorting since it saved with the cell.

It seems that you are creating a cell control for each cell? It’s kind of overkill to simply use a custom editor. Columns have the Editor property that you can assign once and it will use your editor for the cell only when in edit mode saving a lot of resources.

  • You must to post comments
0
0

This code works fine until you sort the DGV. Sorting results in the Data Grid View cells becoming disconnected from their control.

using System.Drawing;
using System.Collections.Generic;
using System.Data;
using Wisej.Web;
namespace wjServiceDirectory
{
public class DataGridViewMultiComboBoxColumn : DataGridViewColumn
{
public DataGridViewMultiComboBoxColumn() : base(new DataGridViewMultiComboBoxColumnCell())
{
  }
}
 public class DataGridViewMultiComboBoxColumnCell : DataGridViewCell
{
public DataGridViewMultiComboBoxColumnCell()
{
this.Control = new MultiColumnComboBox()
{
Border = BorderStyle.None,
Dock = DockStyle.Fill
};
}
  public DataGridViewMultiComboBoxColumnCell(DataTable dtMCC)
{
this.Control = new MultiColumnComboBox()
{
DropDownRows = 16,
ColumnVisible = new List<bool> { true, true, true, true, true, false },
ColumnWidths = new List<int> { 80, 150, 250, 200, 80, 0 },
KeyColumn = 0,
DisplayColumn = 1,
Border = BorderStyle.None,
Dock = DockStyle.Fill,
};
((MultiColumnComboBox)Control).refreshMCC(dtMCC);
}
  protected override bool SetValue(object value)
{
((MultiColumnComboBox)this.Control).BoundValue = value;
   return base.SetValue(value);
}
}

See attached images

  • You must to post comments
0
0

Hi Ewan,

you can query the value like this.

var value = this.dataGridView1.Rows[1].Cells[0].Value;

Hope that helps.

Best regards
Frank

  • Ewan Walker
    Hi Frank found a cool way to do it using an event originating from the multi column combo box that also results in the selected row indicator changing in the master DGV.
  • You must to post comments
0
0

Hi Frank

Thanks that works, however what’s the best way of returning the selected value back to the underlying DGV Cell?

Ewan

  • You must to post comments
0
0

Hi Ewan,

here is the sample that shows how to add a custom column with a custom cell:

customcolumn

customcolumn_code

Download here:

http://wisej.s3.amazonaws.com/support/attachments/Wisej.DGVCustomControlColumn.zip

Best regards
Frank

  • Alex Prinias
    Hi Frank, I know it’s been long after this answer, but the then attached project doesn’t work anymore with 3.2.1. The cells show up empty. What is the updated version of this? Best reagards, Alex
  • You must to post comments
0
0

The CellFormatting event is the wrong place. It can be fired hundreds of times when rendering the grid, editing, etc. You can end up re-creating the cell control multiple times while the grid is getting the data from the server.

We’ll upload a sample for a custom control column shortly.

  • You must to post comments
0
0

Keep getting the attached error.

The Grid does not want to display custom cells, but will do if the size of the grid is modified.

Editing a Date cell causes all the existing custom cells to go blank

Clicking on the header Row to save changes causes DGV to redisplay Properly

Attachment
  • You must to post comments
0
0

This Code works but it is unstable. The Grid Keeps hiding the user controls.

How do I get the Added user controls to inherit the grid back ground colour?

  private void dgvOfficeStaff_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{

if (dgvOfficeStaff[e.ColumnIndex, e.RowIndex] is DataGridViewDateTimePickerCell)
{
((DataGridViewDateTimePickerCell)dgvOfficeStaff[e.ColumnIndex, e.RowIndex]).Format = DateTimePickerFormat.Short;
}
else
{
dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Control = new MultiColumnComboBox();
dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Control.Dock = DockStyle.Fill;
((MultiColumnComboBox)dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Control).BorderStyle = Wisej.Web.BorderStyle.None;

    string strQuery = “Select EmpNo, Forename + ‘ ‘ + Surname as Name, Job, SiteName, Case when DOL = ‘3000-01-01’ then ” else Convert(Varchar(10), DOL, 101) End As DOL, Surname  “;
strQuery += “from Employees E Inner Join Orgchart O on O.CC = E.CC “;
strQuery += “where JobRoleID in (1,2,4,7,10,12) “; // and O.CC = ” + strCC + ” “;
strQuery += “union select ”, ‘Vacant’, ”, ”, ” ,” order by SiteName, Surname”;
mcc_fill((MultiColumnComboBox)dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Control, strQuery);
((MultiColumnComboBox)dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Control).BoundValue = dgvOfficeStaff[e.ColumnIndex, e.RowIndex].Value;
}
}
  • You must to post comments
Showing 14 results
Your Answer

Please first to submit.