0
votes

I have a very simple app with the DataGridView which has bindingSource assigned to its DataSource property. bindingSource is a BindingSource type which has a Data assigned to its DataSource property. Data has just one property ‘string[] files’. The problem is that when I try to select columns to be displayed, using Visual Designer the ‘Selected Columns’ is empty. Why? I can't attached the zip file of the tiny project created by Visual Studio 2017 so I am providing the code:

namespace WindowsFormsAppTest
{
  class Data
  {
    private string[] files;
    public string[] Files { get => files; set => files = value; }
  }
}

using System;
using System.Windows.Forms;

namespace WindowsFormsAppTest
{
partial class Form1
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false. 
    </param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }
    #region "business object"

    #endregion

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.components = new System.ComponentModel.Container();
        this.dataGridView = new System.Windows.Forms.DataGridView();
        this.bindingSource = new System.Windows.Forms.BindingSource(this.components);
        ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
        ((System.ComponentModel.ISupportInitialize)(this.bindingSource)).BeginInit();
        this.SuspendLayout();
        // 
        // dataGridView
        // 
        this.dataGridView.AutoGenerateColumns = false;
        this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        this.dataGridView.DataSource = this.bindingSource;
        this.dataGridView.Dock = System.Windows.Forms.DockStyle.Fill;
        this.dataGridView.Location = new System.Drawing.Point(0, 0);
        this.dataGridView.Name = "dataGridView";
        this.dataGridView.Size = new System.Drawing.Size(800, 450);
        this.dataGridView.TabIndex = 1;
        // 
        // bindingSource
        // 
        this.bindingSource.DataSource = typeof(WindowsFormsAppTest.Data);
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(800, 450);
        this.Controls.Add(this.dataGridView);
        this.Name = "Form1";
        this.Text = "Form1";
        ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
        ((System.ComponentModel.ISupportInitialize)(this.bindingSource)).EndInit();
        this.ResumeLayout(false);

    }

    #endregion
    private DataGridView dataGridView;
    private BindingSource bindingSource;
}
}

Regards,

Janusz

1
You haven't shown any code that populates the array..? Also, do you not need to specify the array as the binding source? It's late here so I may just be tired.Rufus L
I didn't even get to the population of the the array. My dataGridView is not even showing the table. This is what Visual Designer shows an empty "Selected Columns" property. I would have inserted an image here but I don't now how or if it is even possible.Rejkid

1 Answers

0
votes

To bind to a data grid view, the data source must be a collection:

public class Data : List<EclipseFileInfo> { }

public class EclipseFileInfo
{
    private List<string> files;
    private string alias;

    public List<string> Files { get { return files; } set { files = value; } }
    public string Alias { get { return alias; } set { alias = value; } }
}

As you wish to display the Files string[] as a combo box in your grid view, we need to add the combo box manually, and also set its data source manually. We can do the first part in the form constructor:

public Form2()
{
    InitializeComponent();

    dataGridView1.DataBindingComplete += dataGridView1_DataBindingComplete;
    DataGridViewComboBoxColumn comboboxColumn = new DataGridViewComboBoxColumn();

    dataGridView1.Columns.Add(comboboxColumn);

    Data data = new Data();
    data.Add(new EclipseFileInfo() { Alias = "Some Namespace 1", Files = new List<string> { "File1", "File2" } });
    data.Add(new EclipseFileInfo() { Alias = "Some Namespace 2", Files = new List<string> { "File3", "File4" } });
    data.Add(new EclipseFileInfo() { Alias = "Some Namespace 2", Files = new List<string> { "File5", "File6" } });

    dataGridView1.DataSource = data;
}

Then the second part in the DataBindingComplete event handler:

void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        DataGridViewComboBoxCell cell = row.Cells[1] as DataGridViewComboBoxCell;
        cell.DataSource = (row.DataBoundItem as EclipseFileInfo).Files;
    }
}

The final view is like the following:

enter image description here