如何使用来自底层绑定源的行对 datagridview 行执行样式更改?

Posted

技术标签:

【中文标题】如何使用来自底层绑定源的行对 datagridview 行执行样式更改?【英文标题】:How to perform style changes on datagridview rows using rows from the underlying bindingsource? 【发布时间】:2018-12-13 20:08:04 【问题描述】:

我有一个允许用户插入或更新 SQL 表的 win forms 应用程序。当用户点击“上传”时,datagridview 中的数据被合并到一个 sql 表中。我希望 datagridview 行改变颜色以指示插入或更新。

我不知道如何将 datagridview 行关联到 bindingsource 中的底层行。请看我的评论“帮助!”下面

partial class Form1 : Form

    SqlConnection _con;
    BindingSource _bs;
    DataTable _dt;

    public Form1()
    
        // START 
        InitializeComponent();

        // SQL connection
        _con = new SqlConnection(connString);

        // Data binding
        _bs = new BindingSource();
        _dt = new DataTable();
        dataGridView1.DataSource = _bs;
        _bs.DataSource = _dt;            
    

    /// <summary>
    /// Converts the datagridview into a datatable
    /// </summary>
    /// <param name="dgv"></param>
    /// <returns></returns>
    private DataTable GetDataTableFromDGV(DataGridView dgv)
    
        var dt = new DataTable();
        foreach (DataGridViewColumn column in dgv.Columns)
        
            if (column.Visible)
            
                dt.Columns.Add(column.Name.ToString());
            
        

        object[] cellValues = new object[dgv.Columns.Count];
        foreach (DataGridViewRow row in dgv.Rows)
        
            for (int i = 0; i < row.Cells.Count; i++)
            
                cellValues[i] = row.Cells[i].Value;
            
            if ((string)cellValues[0] != "" && (string)cellValues[1] != "" && cellValues[0] != null && cellValues[1] != null)
                dt.Rows.Add(cellValues);
        

        return dt;
    

    private void btnUpload_Click(object sender, EventArgs e)
    
        //Store errors to output to user at the end
        StringBuilder ts = new StringBuilder();

        _dt = GetDataTableFromDGV(dataGridView1);
        if(_dt.Rows.Count > 0)
        
            _con.Open();

            foreach (DataRow dr in _dt.Rows)
            
                using (SqlCommand command = new SqlCommand())
                
                    int returnVal;

                    command.Connection = _con;
                    command.CommandType = CommandType.StoredProcedure;
                    command.CommandText = "dbo.InsertZebraLocationXRef";

                    SqlParameter param1 = new SqlParameter
                    
                        ParameterName = "@Horse",
                        Value = dr.Field<String>("Horse"),
                        SqlDbType = SqlDbType.VarChar
                    ;
                    SqlParameter param2 = new SqlParameter
                    
                        ParameterName = "@Zebra",
                        Value = dr.Field<String>("Zebra"),
                        SqlDbType = SqlDbType.VarChar
                    ;

                    command.Parameters.Add(param1);
                    command.Parameters.Add(param2);

                    try
                    
                        returnVal = (int)command.ExecuteScalar(); //this returns 0 for insert, 1 for update
                        MessageBox.Show(returnVal.ToString());
                    
                    catch (SqlException ex)
                    
                        if (ex.Number == 2627)
                        
                            ts.Append("Primary key constraint violated when entering " + dr.Field<string>("Horse") + " " + dr.Field<string>("Zebra") + Environment.NewLine);
                        
                        if (ex.Number == 515)
                        
                            ts.Append("Cannot insert null value" + Environment.NewLine);
                        
                        Debug.WriteLine(ex.ToString());
                    
                    catch (Exception ex)
                    
                        Debug.WriteLine(ex.ToString());
                    

                    // Help! I want to update the DGV row style here based on the returnVal                     
                
            

            // Output errors to screen
            if (ts.Length > 0)
            
                ts.Append(Environment.NewLine + "The other rows were added successfully." + Environment.NewLine + Environment.NewLine + "Press CTRL + C to copy this box to your clipboard. Please email it to the helpdesk.");
                MessageBox.Show(ts.ToString(), "Written by Vic Street", MessageBoxButtons.OK, MessageBoxIcon.Error);
            
            else
            
                MessageBox.Show("Upload complete", "Upload complete", MessageBoxButtons.OK, MessageBoxIcon.Information);
            
            _con.Close();

        
    


为未来的读者编辑:我通过在数据表中添加另一列“样式”来解决问题,并更改此代码:

                    if (dr.Field<String>("Style") == "1")
                        dataGridView1.Rows[_dt.Rows.IndexOf(dr)].DefaultCellStyle.BackColor = Color.Red;
                    if (dr.Field<String>("Style") == "0")
                        dataGridView1.Rows[_dt.Rows.IndexOf(dr)].DefaultCellStyle.BackColor = Color.Green;

【问题讨论】:

DataTable Row 有一个 RowState 属性。它可以告诉您它是否被添加或修改。 谢谢。如何将 datagridview 行链接到数据表行?这样我就可以根据 DT row.RowState 更新 DGV 行? 不确定我是否理解。如果向 DataTable 添加一行,它应该只出现在网格中,因为它使用它作为 DataSource。 现在就是这样。我想添加额外的功能:当用户点击“上传”时,我们遍历 datagridview 并根据关联数据表行中的值更改行的颜色。 【参考方案1】:

尝试使用 CellFormatting 事件根据行的 RowState 状态设置行的颜色:

void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
  if (e.RowIndex < _dt.Rows.Count) 
    if (_dt.Rows[e.RowIndex].RowState == DataRowState.Added) 
      dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Red;
     else if (_dt.Rows[e.RowIndex].RowState == DataRowState.Modified) 
      dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Blue;
    
  

【讨论】:

谢谢!! Rowindex 是我一直在寻找的功能。这允许我将 datagridview 行链接到数据表行。【参考方案2】:

如果我理解正确,你可以试试这样:

DataGridViewCellStyle highlightCellStyle = new DataGridViewCellStyle();
highlightCellStyle.BackColor = Color.Green;
dataGridView1.CurrentRow.DefaultCellStyle = highlightCellStyle;

我认为,以返回样式为基础颜色不应该是一个问题。

【讨论】:

我该怎么做? Foreach(数据表中的行) IF (row.column == "insert") THEN(关联的 datagridview 行颜色变为绿色) 不是您要更改的当前行吗?我看到你有dataGridView1 实例。我想您可以使用它来进行此更改。 是的!如何将 datagridview 行链接到数据表行?这是我正在努力解决的部分。

以上是关于如何使用来自底层绑定源的行对 datagridview 行执行样式更改?的主要内容,如果未能解决你的问题,请参考以下文章

根据包含数字和不包含数字的行对 CSV 中的行进行排序

如何使用 Entity Framework 将多个表中的数据绑定到 datagridview 并使用 CRUD 操作?

合并(与拆分相反)r 中的行对

如何实现c# winform DataGridView添加一行,添加数据后,保存到数据库?

如何按行对数据进行排序? [MYSQL]

从只有一个值不同的行对中获取唯一行(观察)