C#DataGridView和输入表单

时间:2017-10-11 14:47:33

标签: c# forms datagridview controls

我有一个DataGridView与数据库中的数据绑定。我需要创建一个Form,它包含来自单个网格行的数据的输入字段。 Form有30多个输入控件 - TextBoxes,Checkboxes和NumericUpDowns。

现在我采用了这种方法:

  1. 从DataGridView中检索当前行并将值从单元格加载到类实例

  2. 将实例传递给表单并手动填充输入控件

  3. 从表单更新数据库,更新DataGridView

  4. 我想改进一些事情:

    1. 有没有办法从类实例中快速填充所有输入控件?
    2. 除了手动订阅事件处理程序上的每个控件之外,还有什么方法可以确定哪些输入控件已更改其值?
    3. 有没有办法改善这一切,例如做得更有效率?

2 个答案:

答案 0 :(得分:2)

如果您已经传入DataRow,那么您可以传入DataTable以及标识该表中行的内容。如果您想在表单退出时立即提交更改,也可以选择使用适配器。然后,您可以创建该表的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。

答案 1 :(得分: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处理程序(每个编辑控制类),而不是每个编辑框都有一个。