2017-10-11 87 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处理一次(每个编辑控逆变类),而不是按你有充分的编辑框一个。