2
votes

In my C# program I have a windows form (Winforms) containing a datagridview. The last column of this datagridview is a datagridviewcomboboxcolumn, and each comboboxcell (in each row) has its own datasource.

As there can be a lot of rows, I want to make a binding to populate the datagridview quickly. I already tried to bind the first columns then populate the datasources of the comboboxes afterwards (in the RowsAdded event), but it takes too much time.

My class Data is as follows :

public class Data
    {
        public string _aaa { get; private set; }

        public string _bbb { get; private set; }

        public string _ccc { get; private set; }

        public List<Room> _rooms_list { get; private set; }
...
}

And the Room class contains the following members :

public ElementId Id { get; }
public virtual string Name { get; set; }

When the datasource of the datagridview is bound to a list of Data objects, I want the corresponding comboboxcell to be filled with the corresponding list of Room objects, with Name as DisplayMember and Id as ValueMember.

I searched on the web but didn't find the answer if it's possible or not.

Thanks a lot for your help.

Edit

More info : I want to let the user select the desired Room among a list of detected/found Rooms, so that's why I chose comboboxes. The results of my calculation already are shown as strings in two of the (bound) string columns.

I also want to make the whole thing sortable, so I use a SortableBindingList to bind the DGV with the list of Data objects : mainDataGridView.DataSource = new SortableBindingList<Data>(_data);

1
winforms of wpf? - Mong Zhu
Could you post some code of XAML or how you create your datagridview? - Keyur PATEL
You stated in a comment that… ”Each comboboxcell contains between 1 and 4 room items. But there can be many rows.”... If this is the case, then, the posted class Data not only appears to be missing a Room value variable, but it seems awkward for the Data object to contain MULTIPLE Room values attached to that object. Since these MULTIPLE Room values are used for a ComboBox cell in the grid, it would appear only ONE (1) value would be needed for that Data object for each row.???? - JohnG
Example 1) If the combo box list has “Room1”, Room2” and “Room3”… where would the Data object keep what the user selected? If the combo box contains the values above… where in the Data object are you putting this value to show what Room the user selected? - JohnG
Example 2) Each row may have different values in the combo boxes, however, after the grid is filled, each rows combo box cell would display only ONE (1) of the values in the combo box. Given this, it would appear the Data class is missing this selected Room value for that Data object. Also as stated above, it seems awkward to have EACH Data object contain values that it will NEVER use… i.e. the values in its List<Room> _rooms_list that were NOT selected by the user. - JohnG

1 Answers

0
votes

If you have many rooms in your list, it will be slow to create a new combo-box for each cell as you're already experiencing. I recommend creating one combo-box in code and then adding it to each cell.

Edit: If you're only using the grid for display, you can enhance the performance by simply displaying the rooms as text instead of combo-boxes. You can then denote the selected room by changing the font style (e.g. bold) or color, or by adding some symbol (e.g. asterisk) or word (e.g. [selected]). Separate each room with a new line. Here is an example function, but I don't know how your rooms are selected, so let's assume that you have a bool Selected { get; set; } in your Room class:

string ListRooms(List<Room> rooms){
    string result = "";
    foreach(Room r in rooms){
        result += r.Selected ? "* " : "";
        result += r.Name + "\r\n";
    }
    return result;
}

Now in the OnRowsAdded event, you can call this function and display the result in a simple text cell.

Edit 2: If you're allowing the users to select a room from the list of available rooms, and this list is different from one row to another, then combo-boxes are what we usually use for that purpose. However, if you have many rows then it takes longer to load like you're experiencing.

In that case, you're best bet is to not load the combo-boxes at the beginning. Leave them empty and when the user clicks on a combo-box to select a room, use Ajax to fetch the list of rooms for that row from the server and populate the combo-box using JavaScript. This solution will perform well, but the page may become a little heavy if the user has to select a room for all rows. I believe that all modern browsers will still be capable of handling it smoothly, but it might become and issue if your users use your web application on a mobile device.

Alternatively, you can use popups instead of combo-boxes. Replace the combo-boxes with buttons or links. They can read something like "Select a Room". When the user clicks on the button/link, use Ajax to load a popup with a list of available rooms for that row. The user selects a room from the list and clicks the button to close the popup then you display the select room using JavaScript either on the button/link that's used to open the popup, or in a separate column for the selected rooms which can be initially blank. This solution is easier to implement (you can use jQuery or Bootstrap), more flexible (you can display whatever you want on the popup), and performs perfectly regardless of the number of rows.