For datagridview.NET winforms, I would like the combobox column to have a different set of values ​​for each row

I have a DataGridView that I bind to POCO. Work with data works for me. However, I have added a combobox column that I want to be different for each row. In particular, I have a grid of purchased items, some of which have dimensions (for example, Adult XL, Adult L), while other items do not have a size (for example, β€œMagnet for cars”).

Therefore, in essence, I want to change the DATA SOURCE for the combobox column in the data grid. It can be done?

In what event can I connect, which will allow me to change the properties of certain columns for EACH ROW? A valid alternative is to change the property when the user clicks or inserts tabs in a row. What is this event?

Set

EDIT
I need more help with this issue. With Triduses, I'm so close, but I need a little more information.

First, when asked if the CellFormatting event is really the best / only event to change the DataSource for the combo column. I ask because I am doing something quite resource intensive, not just formatting the cell.

Secondly, a cellular formatting event is triggered only by hovering over a cell. I tried setting the FormattingApplied property inside if-block and then checking it in if-test , but this returns a strange error message. My ideal situation is that I would apply a change to the data source for the combo box once for each row, and then execute it.

Finally, in order to set the data source in colombm combobox, I have to be able to block Cell inside my if block of type DataGridViewComboBoxColumn so that I can fill it with rows or set a data source or something like that. Here is the code that I have right now.

Private Sub ProductsDataGrid_CellFormatting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles ProductsDataGrid.CellFormatting If e.ColumnIndex = ProductsDataGrid.Columns("SizeDGColumn").Index Then ' AndAlso Not e.FormattingApplied Then Dim product As LeagueOrderProductInfo = DirectCast(ProductsDataGrid.Rows(e.RowIndex).DataBoundItem, LeagueOrderProductInfo) Dim sizes As LeagueOrderProductSizeList = product.ProductSizes sizes.RemoveSizeFromList(_parentOrderDetail.SizeID) 'WHAT DO I DO HERE TO FILL THE COMBOBOX COLUMN WITH THE sizes collection. End If End Sub 

Please, help. I was completely stuck, and this task subject had to go an hour, and now I am 4 hours. By the way, I can also resolve this by taking a completely different direction with him (so far I can do it quickly).

Set

+4
source share
5 answers

I did not select the event for changing the displayed values ​​in the combobox for each row ... Take a look at this approach (example), it is very simple and easy to implement and does exactly what you want IMHO :.

  • Declare the Item class with two simple properties (Name, Type)

  • Create a DataGridView with two columns (one for Name and one for Type with ColumnType = DataGridViewComboBoxColumn and dataPropertyName = Type)

  • Attach your (I guess) poco list to a DataGridView

  • And after that, the loop repeats only through your collection of strings; grab a DataGridViewComboBoxColumn for this row ; Change the property of the elements based on the criteria that you have for poco in this line .

I leave this for you to grab poco for a specific row or, alternatively, read some properties from hard-coded columns in a row ...

Here is a sample code:

 namespace DataGridViewCustomComboboxItemsPerRow { public partial class Form1 : Form { public Form1() { InitializeComponent(); List<int> types = new List<int>(); List<Item> items = new List<Item>(); Item item; for (int i = 0; i < 100; i++) { item = new Item(); item.Name = "Item" + i.ToString(); item.Type = i; items.Add(item); types.Add(i); } //typeDataGridViewComboBoxColumn.DataSource = types; itemBindingSource.DataSource = items; } private void Form1_Shown(object sender, EventArgs e) { DataGridViewComboBoxCell dgvc; for (int i = 0; i < dataGridView1.Rows.Count; i++) { dgvc = (DataGridViewComboBoxCell)dataGridView1.Rows[i].Cells[1]; // Your CUSTOM code here, I just did some stupid thing here... dgvc.Items.Add(i - 1); dgvc.Items.Add(i); dgvc.Items.Add(i + 1); } } } public class Item { private string _name; private int _type; public string Name { get { return _name; } set { _name = value; } } public int Type { get { return _type; } set { _type = value; } } } } 

The code is in C #, but quite simple, so I think this will not cause problems in VB.NET. And this code really does a one-time loop (O (n)) to set up combos for different lines and do it.

Hope this helps. Jupe.

+2
source

No, unfortunately, no. What you will need to use is the CellFormatting event .

This will work for each cell, but you can understand if you are in the correct column by checking the column index of the cell, and then you can do your logic if you are in the column that you want to work with.

If you decide you want to change it when they select a row, and not when it is displayed, you can use RowEnter instead.

Here is sample code on how to use this event. This sets the column to have an image in it.

  Private Sub dgActiveOccurrences_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgActiveOccurrences.CellFormatting If e.ColumnIndex = dgActiveOccurrences.Columns("colActiveUnreadFlag").Index Then Dim occ As Occurrence = DirectCast(dgActiveOccurrences.Rows(e.RowIndex).DataBoundItem, Occurrence) If occ.LastReadBy <> OccurrenceSession.Self.UserManager.MyStaffRecord.StaffId Then e.Value = My.Resources.Icon_UnreadFlag End If End If End Sub 
+3
source

I'm not sure how much this is possible for you. Can you try the same thing in the dataGridView1_DataBindingComplete event

 foreach (DataGridViewRow var in dataGridView1.Rows) { if (var.Cells[0] is DataGridViewComboBoxCell) { (var.Cells[0] as DataGridViewComboBoxCell).Items.Add("first col values"); } if (var.Cells[1] is DataGridViewComboBoxCell) { (var.Cells[1] as DataGridViewComboBoxCell).Items.Add("second col values"); } } 
0
source

If you cannot add a row to this grid, you can use the DataBindingComplete event, and this event will be fired when the grid completes the binding of its data, and if you can add rows, you will have to add the NewRowNeeded event this event fired when you click on a new line at the bottom of the grid and you won’t worry about filling the same combo several times

0
source

You can do this with CellBeginEdit . Handle the event, check if the editable column is your DataGridViewComboBox column and change the items in the drop-down list.

This may not work if you are linking a data source to a list. I just tried this manually by adding a list of elements:

 void grid_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) { if (grid.Columns[e.ColumnIndex].Name == "MyComboColumn") { // get the value of a different cell in this row that will be used to determine which values are in the combobox string other_value = grid[0, e.RowIndex].Value.ToString(); // get the combobox cell being edited DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)grid[e.ColumnIndex, e.RowIndex]; // update the list of items in the combobox cell.Items.Clear(); if (other_value == "something") cell.Items.AddRange(new object[] { "Value1", "Value2" }); else cell.Items.AddRange(new object[] { "Value3", "Value4" }); } } 

Note: this code is not verified, I am not on my development machine at the moment.

0
source

Source: https://habr.com/ru/post/1337382/


All Articles