2016-05-17 130 views
1

我使用兩個連接到相同數據庫的DataGridView s和BindingSource s創建了一個主 - 詳細視圖。數據庫有兩個表格,我在它們之間建立了一個主 - 細節視圖,其後是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."); 
} 
} 

它工作得很好。接下來,我向主人添加了一個自定義列,並遵循相同的教程使用此片段編輯主視圖的外觀。

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

現在我想在選擇不同的主設備時獲取每個詳細視圖中的行數。我會將其添加到自定義列中。這是我卡住的地方。我如何從最後一個代碼片段中的單元格格式化程序事件訪問計數?我也可以訪問視圖和數據源。

回答

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數據時。

+0

真棒的答案,謝謝你,讓它工作! – milez