将多行从 form1 中的 gridview 传递到 form2 并等待按钮单击

Passing multiple rows from gridview in form1 to form2 and wait for a button click

我有这段代码,将多行从 form1"FrmPaint" 中的 gridview 传递到 form2 "OptionsPaint",然后将这些数据传递到 form1"FrmPaint" 中的 gridview2

OptionsPaint OPaint = new OptionsPaint();        
    private void btnAdd_Click(object sender, EventArgs e)
    {
        int[] selectedRows = gridView1.GetSelectedRows();
        for (int i = 0; i < selectedRows.Length; i++)
        {
            DataRow rowGridView1 = (gridView1.GetRow(selectedRows[i]) as DataRowView).Row;
            if (OPaint == null || OPaint.IsDisposed)
            OPaint = new OptionsPaint();
            OPaint.Show();

            OPaint.bsRepere.Text = rowGridView1["BS"].ToString() + " " + "Repère: " + rowGridView1["Repère"].ToString();
            OPaint.quantity.EditValue = rowGridView1["Reste Qté"];

            OPaint.OK.Click += (sender1, e1) =>
             {
                 DataRow row = dt.NewRow();
                 row[0] = rowGridView1["BS"];
                 row[1] = rowGridView1["Repère"];
                 row[2] = rowGridView1["Profil"];
                 row[3] = OPaint.quantity.EditValue;
                 dt.Rows.Add(row);
               OPaint.Close();
            }; 
         }
     }

当我 select 只有一行代码工作正常,但是当我 select 多行时 form2"OptionsPaint" 只显示一次,最后一个值 selectd 在 gridview 中来自 from1。有没有办法停止代码,直到用户单击按钮,然后完成其余代码。

以下是您的代码所做的等效操作:

//imagine it is a form with a single label and a button
OptionsForm of = new OptionsForm();

string[] sa = new string[]{ "a","b","c" };

foreach(string s in sa){
  of.Show();
  of.MyLabel.Text = s;
  of.MyButton.Click += (some event handler);
}

如果你有 3 个字符串,这段代码将 运行 完全循环 3 次:第一次是 运行s,如果 OptionsForm of 没有显示它会显示。在已经可见的窗体上重复调用 Show() 不会执行任何操作。

然后在接下来的几毫秒内,标签文本将更新 3 次(如此之快,您根本看不到它,尤其是当您的代码 运行ning 没有 window 消息时已处理)并最终设置为 "c" - 你永远不会看到 "a" 或 "b"。您的按钮单击事件将附加 3 个处理程序。我不完全确定这是否有帮助,但我怀疑没有,因为在您的情况下,它将 X 行放入相同的 dt 中。

这就是为什么当您 select 多行时只显示最后一行;每个循环都会覆盖前一个循环,没有任何东西会停止循环 运行 以毫秒为单位完成

那该怎么办呢?

如果您希望此表单对每个 selected 项目显示一次,那么如果用户 selected 10 个项目,则此表单将连续出现 10 次,他们必须单击10 次摆脱它然后将 OPaint.Show() 移动到 AFTER 你附加按钮单击事件处理程序并使其 ShowDialog 而不是 Show:

var dResult = OPaint.ShowDialog();

您需要进行一些额外的设置才能将表单用作对话框,因为您需要声明哪个按钮是确定按钮,哪个按钮是取消按钮。请参阅 MSDN https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.form.dialogresult?view=netframework-4.7.2 中的示例 - 设置 ok/cancel 按钮的 .dialogresult 并告诉表单 accept/cancel。从按钮单击处理程序中删除对 Close() 的指令 - 控制对话框类型表单的按钮会导致表单在单击时自动关闭

您将需要一个 if 来测试 dResult 以了解用户是单击“确定”还是“取消”,并进行相应处理 - 我不知道如果他们单击“取消”您会怎么做?

调用 ShowDialog 将导致代码在该点停止,直到用户做出决定,就像消息框一样

最后,我只想指出这样做的用户界面非常烦人。您应该考虑只有一个对话框来询问 "ok to update all these 10 rows?" 或者可能有一个可以同时显示和更新多个内容的表单