1

I have a custom control that inherits from a DataGridView. It has pre-defined columns.

One of the columns is a ComboBox column. I want it so that users can select an hour of the day, so it binds to a datasource that is an array of integers, from 0 to 24.

Everything is OK at design time (when I drop the control onto a form). The problem I get is that run-time, the designer tries to add the datasource twice, and then causes an error.

Here is the salient code:

//Constructor for teh usercontrol        
    public OutageGrid()
    {
        base.AutoGenerateColumns = false;       //Hidden from intellisense, but needed to prevent columns being duplicated by the designer.
        InitializeComponent();
    }

private int[] Hours = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };


        /// <summary>
    /// This is called after the usercontrol is added to another container (form).  This is used to add the columns to the
    /// control, to avoid the issue where the columns get duplicated at runtime.
    /// </summary>
    protected override void InitLayout()
    {
        //base.InitLayout();
        SetColumns();
    }
    private void SetColumns()
    {
        base.Columns.Clear();

        base.Columns.Add("ID", "ID");
        base.Columns.Add("IAPCode", "IAPCode");
        base.Columns.Add("Venture", "Venture");

        DataGridViewComboBoxColumn startHourColumn = new DataGridViewComboBoxColumn();
        startHourColumn.HeaderText = "Start Hour";
        startHourColumn.DataSource = Hours;
        startHourColumn.ValueType = typeof(int);
        base.Columns.Add(startHourColumn);
    }

You can see that I generate the columns in the BeginInit() event, as I was finding that if I try to do it directly from the constructor, the columns were getting duplicated at runtime.

When I try to actually compile and run the program, the designer creates this code (this is from my Form.Designer):

            // 
        // dataGridViewComboBoxColumn16
        // 
        this.dataGridViewComboBoxColumn16.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
        this.dataGridViewComboBoxColumn16.DataSource = new int[] {
    0,
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    11,
    12,
    13,
    14,
    15,
    16,
    17,
    18,
    19,
    20,
    21,
    22,
    23,
    24};
        dataGridViewCellStyle8.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
        this.dataGridViewComboBoxColumn16.DefaultCellStyle = dataGridViewCellStyle8;
        this.dataGridViewComboBoxColumn16.HeaderText = "Start Hour";
        this.dataGridViewComboBoxColumn16.Items.AddRange(new object[] {
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24});
        this.dataGridViewComboBoxColumn16.Name = "dataGridViewComboBoxColumn16";
        this.dataGridViewComboBoxColumn16.Width = 61;

You can see that it has set the DataSource to be the array of hours, but then it then tries to add a range of values. This causes an exception:

Additional information: Items collection cannot be modified when the DataSource property is set.

I dutifully go into the designer and delete this code. Re-run and it compiles, until I make a change to my control or project.

Anyone know what's going on, and how to avoid this?

ainwood
  • 992
  • 7
  • 17
  • I tried changing the code to add the combobox items using items.addrange() instead of setting a datasource, but couldn't get that to work. – ainwood Aug 08 '16 at 04:57
  • In the end, I modified what I was doing. Because the columns I am adding reflect the type of data that I want to add, I did the following: 1.) A created a class to hold the data to be displayed. 2.) I pass a collection of that class to a custom field of the datagridview. 3.) in the "set" accessor of that field, I run the code to add the columns. I.e. the columns don't get added in the Visual Studio designer at all; they get added at run time, immediately prior to actually have something to display. – ainwood Aug 30 '16 at 07:55

0 Answers0