【问题标题】:Obtaining the number of elements in details with Master-Detail view with database as source以数据库为源,使用 Master-Detail 视图获取详细元素的数量
【发布时间】:2016-09-13 05:10:33
【问题描述】:

我使用两个DataGridViews 创建了一个主从视图,其中BindingSources 连接到同一个数据库。数据库有两个表,我在Microsoft tutorial 之后在它们之间建立了一个主从视图。这是负责它的代码:

private void GetData()
{
try
{
    // Specify a connection string. Replace the given value with a 
    // valid connection string for a Northwind SQL Server sample
    // database accessible to your system.
    String connectionString =
        "Integrated Security=SSPI;Persist Security Info=False;" +
        "Initial Catalog=Northwind;Data Source=localhost";
    SqlConnection connection = new SqlConnection(connectionString);

    // Create a DataSet.
    DataSet data = new DataSet();
    data.Locale = System.Globalization.CultureInfo.InvariantCulture;

    // Add data from the Customers table to the DataSet.
    SqlDataAdapter masterDataAdapter = new
        SqlDataAdapter("select * from Customers", connection);
    masterDataAdapter.Fill(data, "Customers");

    // Add data from the Orders table to the DataSet.
    SqlDataAdapter detailsDataAdapter = new
        SqlDataAdapter("select * from Orders", connection);
    detailsDataAdapter.Fill(data, "Orders");

    // Establish a relationship between the two tables.
    DataRelation relation = new DataRelation("CustomersOrders",
        data.Tables["Customers"].Columns["CustomerID"],
        data.Tables["Orders"].Columns["CustomerID"]);
    data.Relations.Add(relation);

    // Bind the master data connector to the Customers table.
    masterBindingSource.DataSource = data;
    masterBindingSource.DataMember = "Customers";

    // Bind the details data connector to the master data connector,
    // using the DataRelation name to filter the information in the 
    // details table based on the current row in the master table. 
    detailsBindingSource.DataSource = masterBindingSource;
    detailsBindingSource.DataMember = "CustomersOrders";
}
catch (SqlException)
{
    MessageBox.Show("To run this example, replace the value of the " +
        "connectionString variable with a connection string that is " +
        "valid for your system.");
}
}

而且效果很好。接下来,我向主视图添加了一个自定义列,并按照相同的教程使用此 sn-p 编辑主视图的外观。

// Changes how cells are displayed depending on their columns and values.
private void masterGridView_CellFormatting(object sender, 
    System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
{
    // Set the background to red for negative values in the Balance column.
    if (masterGridView.Columns[e.ColumnIndex].Name.Equals("CustomColumn"))
    {

            e.CellStyle.BackColor = Color.Red;
            e.CellStyle.SelectionBackColor = Color.DarkRed;            
    }
}

现在我想在选择不同的主视图时获取每个详细视图中的行数。我会将其添加到自定义列中。这就是我卡住的地方。如何从最后一个 sn-p 中的单元格格式化程序事件中访问计数?我也可以访问视图和数据源。

【问题讨论】:

    标签: c# database data-binding datagridview datasource


    【解决方案1】:

    加载数据并添加自定义列后,尝试使用DataRow.GetChildRows 方法计算详细信息视图中的行数。这将设置初始值:

    DataSet ds = this.masterBindingSource.DataSource as DataSet;
    string tableName = this.masterBindingSource.DataMember;
    
    foreach (DataGridViewRow row in this.masterDataGridView.Rows)
    {
        row.Cells["CustomColumn"].Value = ds.Tables[tableName].Rows[row.Index].GetChildRows(ds.Relations[0]).Length;
    }
    

    如果您允许用户从详细信息视图中添加/删除行,我建议首先设置以下 (*)

    this.masterDataGridView.AllowUserToAddRows = false;
    this.detailsDataGridView.AllowUserToAddRows = false;
    

    从那里您需要附加到RowChangedRowDeleting 事件的详细信息DataTable

    ds.Tables["Orders"].RowChanged += Details_RowChanged;
    ds.Tables["Orders"].RowDeleting += Details_RowChanged;
    

    在该事件处理程序中,我们将再次基于GetChildRows 方法设置主行的自定义列值。特别注意事项:

    • 对于已删除的行,该计数尚未反映删除。我们会考虑到这一点。
    • 对于添加的行,除非您已经在添加时设置了父行,否则您需要在此处进行处理。

    话虽如此:

    private void Details_RowChanged(object sender, DataRowChangeEventArgs e)
    {
        int change = 0;
        DataSet ds = this.masterBindingSource.DataSource as DataSet;
    
        if (e.Action == DataRowAction.Add)
        {
            DataRow parent = null;
    
            foreach (DataRow dr in ds.Tables["Customers"].Rows)
            {
                if (dr["CustomerID"].Equals(e.Row["CustomerID"]))
                {
                    parent = dr;
                    break;
                }
            }
    
            e.Row.SetParentRow(parent);
        }
        else if (e.Action == DataRowAction.Delete)
        {
            change = -1;
        }
    
        DataRow row = e.Row.GetParentRow(ds.Relations[0]);
        int index = ds.Tables["Customers"].Rows.IndexOf(row);
    
        this.masterDataGridView.Rows[index].Cells["CustomColumn"].Value = row.GetChildRows(ds.Relations[0]).Length + change;
    }
    

    (*)应以编程方式添加行 - DataTable.Rows.Add(params object[] values) - 添加到数据绑定 DataGridView 时。

    【讨论】:

      猜你喜欢
      • 2012-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-24
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      相关资源
      最近更新 更多