以编程方式将可编辑的TextBox添加到DataTable - Column需要有效的DataType

时间:2016-02-24 14:10:30

标签: c# datagridview datatable datacolumn

我正在尝试使用动态生成的DataGridView填充DataTable,我需要其中一列成为可编辑的TextBox

这是我的应用程序中填充数据网格视图的片段:

public static void PopulatePOLines(MSSQLConnection mssqlConnection, string supplierAccountNumber, DataGridView poLineList)
{
    // Init
    DataTable dataTable = new DataTable();
    DataColumn dataColumn;
    DataRow dataRow;
    List<POLine> poLines = new List<POLine>();

    // Define sage sku column
    dataColumn = new DataColumn();
    dataColumn.DataType = Type.GetType("System.String");
    dataColumn.ColumnName = "sageSku";
    dataTable.Columns.Add(dataColumn);

    // Define required quantity column
    dataColumn = new DataColumn();
    dataColumn.DataType = Type.GetType("System.Int32");
    dataColumn.ColumnName = "requiredQuantity";
    dataTable.Columns.Add(dataColumn);

    // Define on pop quantity column
    dataColumn = new DataColumn();
    dataColumn.DataType = Type.GetType("System.Int32");
    dataColumn.ColumnName = "onPOPQuantity";
    dataTable.Columns.Add(dataColumn);

    // Define order quantity column
    dataColumn = new DataColumn();
    dataColumn.DataType = Type.GetType("System.Windows.Forms.TextBox");
    dataColumn.ColumnName = "orderQuantity";
    dataTable.Columns.Add(dataColumn);

    // Consolidate & populate po lines from failed allocations by supplier from db
    try
    {
        // Query database
        List<Dictionary<string, object>> results = mssqlConnection.ExecuteReader(
            "... snipped...",
            new Dictionary<string, object>()
            {
                { "SupplierAccountNumber", supplierAccountNumber }
            });

        // Parse result
        foreach (Dictionary<string, object> dbRow in results)
        {
            // Parse row field value
            var sageSku = dbRow["SageSku"].ToString();
            var quantity = Convert.ToInt32(dbRow["Quantity"]);

            // Check if this failed allocation line is known
            var poLine = poLines.Find(s => s.SageSku == sageSku);

            // If this line isn't known
            if (null == poLine)
            {
                // Workout quantity on pop for this sage sku
                var onPOPQty = mssqlConnection.ExecuteScalar<int>(
                    "... snipped...",
                    new Dictionary<string, object>()
                    {
                        { "SageSku", sageSku }
                    });

                // Insert a new record
                poLines.Add(new POLine()
                {
                    SageSku = sageSku,
                    RequiredQty = quantity,
                    OnPOPQty = onPOPQty
                });
            }
            else
            {
                // Update existing record
                poLine.RequiredQty += quantity;
            }

            // Clean-up
            sageSku = null;
        }

        // Clean-up
        results = null;

        // Iterate through po lines
        foreach (POLine poLine in poLines)
        {
            dataRow = dataTable.NewRow();
            dataRow["sageSku"] = poLine.SageSku;
            dataRow["requiredQuantity"] = poLine.RequiredQty;
            dataRow["onPOPQuantity"] = poLine.OnPOPQty;
            dataRow["orderQuantity"] = (poLine.OnPOPQty > poLine.RequiredQty ? 0 : (poLine.RequiredQty - poLine.OnPOPQty));
            dataTable.Rows.Add(dataRow);
        }
    }
    catch (Exception ex)
    {
        ShowError("Failed to consolidate & populate purchase order lines by selected supplier.", ex);
    }

    // Set data source
    poLineList.DataSource = new DataView(dataTable);

    // Clean-up
    dataTable = null;
    dataColumn = null;
    dataRow = null;
    poLines = null;

    // Update column header text
    poLineList.Columns[0].HeaderText = "Sage Sku";
    poLineList.Columns[1].HeaderText = "Required Qty";
    poLineList.Columns[2].HeaderText = "On POP Qty";
    poLineList.Columns[3].HeaderText = "Suggested Order Qty";
}

执行此代码时,出现以下错误:

  

列需要有效的DataType。

我在这里做错了什么?

如果我将orderQuantity列的DataType设置为System.Int32,则数据网格视图会正确呈现我的数据,但它不可编辑:

enter image description here

我有什么想法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:1)

我已经解决了这个问题。

我将数据类型保留为System.Int32,然后在可视化设计器中,我点击了DataGridView并勾选了Enable Editing,然后在填充数据源的代码中,我'最后在最后添加了以下内容:

// Disallow editting on certain columns
poLineList.Columns[0].ReadOnly = true;
poLineList.Columns[1].ReadOnly = true;
poLineList.Columns[2].ReadOnly = true;

我的网格上有4列,所以上面会将前三列设为只读,其他列可编辑,这只是第4列(我想要编辑)。

感谢Steve

答案 1 :(得分:0)

As indicated in the MSDN,DataColumn.DataType仅支持一组特定的数据类型(大多数是基本类型,但也有一些例外)。不幸的是,你无法直接添加TextBox。

但是,你看过DataGridViewTextBoxColumn Class了吗?您应该能够将列创建为此类的实例,而不是使用TextBox填充的普通列。

也可以创建DataGridView模板,并将所需的列作为此类之一(您可以从设计视图中定义列),而将其他列留空则填充在代码中。

答案 2 :(得分:0)

如果我将orderQuantity列的DataType设置为System.Int32,则datagrid视图会正确显示我的数据,但它不可编辑:

在这种情况下,如果您的列是主键,它将不允许您编辑,因为它是PK。确保可编辑列不是PK。