【问题标题】:Can C# BindingSource contain array of stringsC# BindingSource 可以包含字符串数组吗
【发布时间】:2020-04-27 05:24:07
【问题描述】:

我有一个非常简单的应用程序,其 DataGridView 已将 bindingSource 分配给其 DataSource 属性。 bindingSource 是一个 BindingSource 类型,它有一个 Data 分配给它的 DataSource 属性。数据只有一个属性‘string[] files’。问题是当我尝试选择要显示的列时,使用可视化设计器时,“选定的列”是空的。为什么? 我无法附加 Visual Studio 2017 创建的小项目的 zip 文件,所以我提供了代码:

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;
}
}

问候,

贾努斯

【问题讨论】:

  • 您没有显示任何填充数组的代码..?另外,您不需要将数组指定为绑定源吗?时间不早了,可能有点累了。
  • 我什至没有得到阵列的人口。我的 dataGridView 甚至没有显示表格。这就是可视化设计器显示一个空的“选定列”属性。我会在这里插入一张图片,但我现在不知道如何或是否可能。

标签: c# datagridview combobox


【解决方案1】:

要绑定到数据网格视图,数据源必须是集合:

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; } }
}

由于您希望在网格视图中将 Files string[] 显示为组合框,我们需要手动添加组合框,并手动设置其数据源。我们可以在表单构造函数中做第一部分:

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;
}

然后是DataBindingComplete事件处理程序中的第二部分:

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;
    }
}

最终的视图如下:

【讨论】:

  • 我认为我们彼此误解了。如果将 Data.css 属性从 string[] 更改为 string: public class Data { private string files;公共字符串文件 { 获取 => 文件;设置 => 文件 = 值;您将看到 Visual Designer 立即开始显示“文件”列。我猜我的数据不是列表没有任何问题,但是我的 Files 属性是字符串 [] 而不是字符串存在问题。我看不到任何插入视觉设计器显示的图像的选项。
  • 我认为您在这里没有正确使用数据绑定。如果您尝试在网格视图中显示数组(文件)的内容,则拥有数据源(不是集合)将在那里仅显示一条记录。我认为您希望网格视图在文件字符串 [] 中的每一行中显示您的字符串之一,但这不是数据绑定的工作方式。
  • 例如,如果您只是将数据更改为扩展 List,您看到的唯一列将是“Length”,因为这是字符串公开的唯一公共属性。 !!!当您的数据源是 T 类型的集合时,网格列是 T 的公共属性,并且每个网格行显示一个 T 实例。 !!!
  • 我已将数据更改为:namespace WindowsFormsAppTest { public class Data : List&lt;EclipseFileInfo&gt; { } public class EclipseFileInfo { public string[] Files { get =&gt; files; set =&gt; files = value; } private string[] files; public string Alias { get =&gt; alias; set =&gt; alias = value; } private string alias; } }
  • 所以现在我有 Data 类扩展 List 和 EclipseFileInfo 包含两列 Alias 和 Files。我已经分配给 DataGridView.DataSource BindingSource 类型(变量名 bindingSource)。我已经为该 bindingSource.DataSource 分配了数据。所以我希望 VisualDesigner 应该显示两列可供选择:“文件”和“别名”,但它只显示别名。我究竟做错了什么?如何使 Files 可见并成为 ComboBox 控件?
猜你喜欢
  • 1970-01-01
  • 2014-10-18
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多