将 WinForm 与 DatagridView 同步

发布于 2024-08-09 20:17:21 字数 312 浏览 2 评论 0原文

我有一个带有 DataGridView 的表单,其中 DataSource 是表的 BindingSource。该视图将有一个单行选择和一个用于删除、编辑弹出表单中当前选定行的按钮,以及一个也将使用相同表单的插入按钮。

我的问题是如何将弹出表单与当前行同步?

我尝试使用 RowStateChanged 事件来获取并存储要在表单中使用的当前选定的行,但我无法做到。事件结束后,我得到了之前选择的行。

我还不明白在 C# 中如何拥有单个记录集并知道它是当前记录,即使它是以某种方式插入的新记录,一旦在表单中输入的所有数据将同时显示在 DataGridView 中。

I have a Form with a DataGridView which DataSource is a BindingSource to a table. This view will have a single row selection and a button to delete, edit the current selected row in a popup Form and a insert button that will use the same Form as well.

My question is how can I sync the pop Form with the current row?

I tryied to use the RowStateChanged event to get and store the current selected Row to be used in the Form but I coudnt. After the event I get the row that was selected before.

Other thing I dont understand yet in C# how to have a single recordSet and know wich is the current record even if its a new being inserted in a way that once in the Form all data being entered will show up at the same time in the DataGridView.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心是晴朗的。 2024-08-16 20:17:21

您不必将表单与当前行同步。这就是 BindingSource 的用途。

当您对 BindingSource 进行简单绑定时,每次当前项发生更改时,绑定控件都会更新,每次绑定控件中的值发生更改时,绑定项中的基础值都会更新。当您进行复杂绑定时(即绑定控件显示 BindingSource 的列表,而不仅仅是当前项),更改 BindingSource 上的 Position还将更改绑定控件中的当前位置,反之亦然。因此,在这种情况下,您希望使用简单绑定来绑定第二个表单上的控件,并使用复杂绑定来绑定第一个表单上的 DataGridView

您需要做的唯一不寻常的事情是确保两种表单使用相同 BindingSource。执行此操作时,单击 DataGridView 中的新行会更新 BindingSource 上的 Position,并且 BindingSource > 将当前绑定项中的值推送到与其绑定的所有简单绑定控件。

这很容易完成。假设 Form1 是带有 DataGridView 的表单,而 Form2 是带有简单绑定控件的表单,请执行以下操作:

Form1 中:

private BindingSource Source = new BindingSource();

Form1_Load(object sender, EventArgs e)
{
    // set Source's DataSource to your DataTable here.
    mainDataGridView.DataSource = source;
    // create DataGridView columns and their bindings here.

    Form2 f2 = new Form2();
    f2.TopMost = true;
    f2.Source = Source;
    f2.Show();
}

在 表格2:

public BindingSource Source { get; set; }

public void Form2_Load(object sender, EventArgs e)
{       
    idTextBox.DataBindings.Add("Text", Source, "id");
    descriptionTextBox.DataBindings.Add("Text", Source, "description")
}

You don't have to sync the form with the current row. That's what a BindingSource is for.

When you do simple binding to a BindingSource, then every time its current item changes, the bound controls get updated, and every time the values in the bound controls change, the underlying values in the bound item get updated. When you do complex binding (i.e. the bound control displays the BindingSource's list, not just the current item), changing Position on the BindingSource will also change the current position in the bound control, and vice versa. So in this case, you want to bind the controls on your second form using simple binding, and the DataGridView on your first using complex binding.

The only unusual thing you need to do is make sure that both forms are using the same BindingSource. When you do that, clicking on a new row in the DataGridView updates the Position on the BindingSource, and the BindingSource pushes the values from the current bound item out to all of the simply-bound controls that are bound to it.

This is easily accomplished. Assuming that Form1 is the form with the DataGridView, and Form2 is the one with the simply-bound controls, do this:

In Form1:

private BindingSource Source = new BindingSource();

Form1_Load(object sender, EventArgs e)
{
    // set Source's DataSource to your DataTable here.
    mainDataGridView.DataSource = source;
    // create DataGridView columns and their bindings here.

    Form2 f2 = new Form2();
    f2.TopMost = true;
    f2.Source = Source;
    f2.Show();
}

In Form2:

public BindingSource Source { get; set; }

public void Form2_Load(object sender, EventArgs e)
{       
    idTextBox.DataBindings.Add("Text", Source, "id");
    descriptionTextBox.DataBindings.Add("Text", Source, "description")
}
溺孤伤于心 2024-08-16 20:17:21

您可以轻松地保持同步,但不能使用 BindingSource。

Windows 窗体数据绑定构建在几个最重要的接口之上:
IList 和 IBindingList。第一个仅负责通过列表中的索引提供对元素的访问(为了简单起见),第二个实际上更复杂。

IBindingList -(由 BindingSource 实现)具有支持的方法:

  • 更改通知
  • 添加新的“空”元素
  • 排序
  • 搜索

对您而言最重要的当然是更改通知。不幸的是 BindingSource 没有实现那段代码。您可以在这里做两件事 - 要么通过更改通知实现您的 BindingSource 版本,要么尝试干扰 DGV 和文本框/组合框事件来更新数据。

就我个人而言,我已经完成了第一个(我可以分享我拥有的代码)。

“我还不明白在 C# 中如何拥有单个记录集并知道它是当前记录,即使它是以某种方式插入的新记录,一旦在表单中输入的所有数据将同时显示在数据网格视图。”

每个表单都有一个 BindingContext 对象,用于保存CurrencyManagers - 每个数据源一个。这样,绑定到同一数据源的每个控件都知道哪条记录是当前的。实际上,BindingNavigator 所做的是扰乱适当的CurrencyManager 并调用其方法。 (我不知道为什么它需要 BindingSource 而不是最小 IList 或完整功能 IBindingList)

You can easily keep it in sync, but not using BindingSource.

Windows Forms data binding is built on top of a few interfaces the most important are:
IList and IBindingList. The first one is just responsible for providing access to elements by their index in the list(to make it simple) the second one actually is more complicated.

IBindingList - (which is implemented by BindingSource) has methods to support:

  • change notification
  • adding new "empty" element
  • sorting
  • searching

The one that is important for you is of course change notification. Unfortunately BindingSource doesn't implement that bit of code. You may do 2 things here - either implement your version of BindingSource with change notification or try to mess with DGV and textboxes/comboboxes events to update the data.

Personally I've done the first one(I can share the code I have).

"Other thing I dont understand yet in C# how to have a single recordSet and know wich is the current record even if its a new being inserted in a way that once in the Form all data being entered will show up at the same time in the DataGridView."

Every form has a BindingContext object that keeps CurrencyManagers - one for each DataSource. That way every control bound to the same data source knows which record is current. Actually what BindingNavigator does is messing with the apropriate CurrencyManager and calling its methods. (I have no idea why it requires BindingSource instead of in the minimum IList or for full functionality IBindingList)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文