2017-10-11 61 views
1

我有一個DataGridView綁定數據庫中的數據。我需要創建一個表單,它具有來自單個網格行的數據的輸入字段。 窗體有30多個輸入控件 - 文本框,複選框和NumericUpDowns。C#DataGridView和輸入表格

現在我用這個方法去:

  1. 檢索從細胞到類實例

  2. 當前行從DataGridView中和負載值傳遞實例的形式和手工填寫輸入控件

  3. 更新表單中的數據庫,更新的DataGridView

我想提高一些事情:

  1. 有沒有什麼辦法能夠迅速填補一個類實例的所有輸入控件?
  2. 除了手動訂閱事件處理程序的每個控件外,是否有任何方法可以確定哪些輸入控件已更改其值?
  3. 有什麼辦法可以改善這個問題嗎?做更有效的事情?
+0

考慮從DataGridView中更新數據庫。 (例如:[1](https://stackoverflow.com/q/27760744/3773066),[2](https://stackoverflow.com/q/8653523/3773066))從後者考慮使用[DataAdapter ](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/updating-data-sources-with-dataadapters)。 – OhBeWise

回答

2

如果您已經傳入一個DataRow,那麼您可以傳遞DataTable和其他標識該表中該行的東西。也可以選擇一個適配器,如果你想立即在form exit上提交更改。然後你可以創建該表的DataView。並將每個編輯控件綁定到該視圖中的字段。事情是這樣的:

public partial class EditForm : Form 
{ 

    DataRow row = null; 
    DataView view; 
    SqlDataAdapter adapter; 

    public EditForm(SqlDataAdapter adapter, DataTable table, int rowId) 
    { 
     InitializeComponent(); 

     this.adapter = adapter; 

     view = table.DefaultView; 
     view.RowFilter = $"ID = {rowId}"; 
     if (view.Count == 0) throw new Exception("no such row"); 
     DataRowView dvr = view[0]; 
     row = dvr.Row; 

     datebox.DataBindings.Add(new Binding("Value", view, "DATE")); 
     stringbox.DataBindings.Add(new Binding("Text", view, "O_STRING")); 

     this.FormClosing += EditForm_FormClosing; 
    } 

    private void EditForm_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     if (row.RowState == DataRowState.Modified) adapter.Update(new DataRow[] { row }); 
    } 
} 

以上假設你的表中有一個名爲ID鍵列和領域DATEO_STRING

這將爲您節省創建中間自定義類實例的麻煩,該實例基於該行,將值移入和移出各種對象,並自動將RowStatae設置在原始表中。

+0

感謝您的支持者,看起來像DataView是我所需要的。但是有什麼方法可以讓輸入控制識別它已經改變了它的價值?例如。如果用戶更改文本,在文本框中使字體變粗體? – Technical

0

Re:價值變化的指標。不知道是否有一個非常優雅的方式來做到這一點。首先,如果我不得不,我會改變背景(或前景)的顏色,而不是字體的大膽。將字體設置爲粗體會改變內容的寬度,這通常很煩人。然後,我會將處理程序添加到TextChanged事件(或ValueChange事件,對於不是基於文本的控件)。您無需爲每個編輯控件編寫自定義處理程序 - 在事件處理程序中,您將獲得指向控件對象的參數object sender。然後你就可以得到綁定到該控件像這樣的東西的字段名稱:

private void stringbox_TextChanged(object sender, EventArgs e) 
{ 
    Control ctrl = (Control)sender; 
    string fieldName = ctrl.DataBindings[0].BindingMemberInfo.BindingMember; 
    if ((string)view[0].Row[fieldName] != ctrl.Text) ctrl.BackColor = Color.Pink; 
} 

這樣你就只需要添加一個框TextChanged處理一次(每個編輯控逆變類),而不是按你有充分的編輯框一個。