【问题标题】:C# DataGridView and Input FormC# DataGridView 和输入表单
【发布时间】:2017-10-11 14:47:33
【问题描述】:

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

现在我采用了这种方法:

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

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

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

我想改进一些东西:

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

【问题讨论】:

  • 考虑从您的DataGridView 更新数据库。 (例如:12)对于后者,考虑使用DataAdapter

标签: c# forms datagridview controls


【解决方案1】:

如果您已经传入 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。

【讨论】:

  • 感谢您的回答,看来 DataView 是我需要的。但是输入控件有什么方法可以识别它已经改变了它的值吗?例如。如果用户更改文本,在 TextBox 中将字体加粗?
【解决方案2】:

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 处理程序(每个编辑控件类),而不是每个您拥有的编辑框一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    相关资源
    最近更新 更多