【问题标题】:Update gui to child winform from parent winform将 gui 从父 winform 更新为子 winform
【发布时间】:2012-11-14 20:42:27
【问题描述】:

我正在尝试做的事情,当我们点击 radform1(Parent) 中的按钮时,隐藏 radform1 然后更新 Form1(child form) 中的 text/label/radgrid 标题文本值, 一旦我们关闭 Form1(child form)..close radform1(Parent) 。

我收到一条错误消息:Invalid OPeration Exception was Un-HandledCross-thread operation not valid 控件 'radPageView1 已从创建它的线程以外的线程访问。

如何使用调用或操作方法来解决此问题?我无法完全理解这个概念。请向我解释我应该在这里做什么...感谢任何帮助!

Form1 frm = new Form1();
        private void radButton1_Click(object sender, EventArgs e) // French Version Button
        {
            timer1.Enabled = true;
            radProgressBar1.Visible = true;
            frm.radGridView1.Columns[0].HeaderText = "Test"; // Change the Radgrid Header Text at Col[0]

        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            ticks++;
            radProgressBar1.Value1 = ticks;
            if (ticks != 100) return;
            timer1.Enabled = false;
            ticks = 0;

            frm.FormClosed += (_, args) => frm.Close();
            frm.Hide();
            frm.Show();

        }

【问题讨论】:

  • 如果您使用 Windows.Form.Timer 类,那么跨线程应该不是问题。任何方式,对于跨线程问题,您可以使用 this.Invoke(delegate...) 或 this.Invoke(MethodInvoker)。另请注意,只要您说 Timer.Enabled,计时器就会立即在后台启动。
  • @zenwalker:你能告诉我,我如何更新我的 gui 中的方法 ovoker。请用一些代码向我解释,以便我理解。谢谢。
  • 刚刚使用了 Windows 窗体 TImer 类,我只是在更新文本框文本值。没有使用任何调用者。 pastebin.com/hbnX9xgC希望能给你一些提示。另请注意,使用 Windows 窗体计时器的缺点是,它与 UI 线程一起运行。因此,如果 UI 线程变得无响应,则说明您的计时器效率低下且不准确。
  • @zenwalker:那么最好的解决方案是什么?从您的代码中,我理解的是使用计时器在同一窗口中更新 gui。我想你知道,我想从另一个窗口更新 gui。可能我没有低估它。
  • 如果我正确理解了您的问题,希望这会有所帮助。再次使用相同的计时器类型,但这次我添加了一个新的表单 Form2,它有一个公共成员(文本框)。单击按钮时,我将值发送到其文本框组件以​​进行显示。只需摆弄代码,您就会得到它pastebin.com/KvMXjJm6

标签: c# winforms user-interface delegates invoke


【解决方案1】:

我不知道我是否理解得很好,但我认为你需要这样的东西:

public static void InvokeIfRequired(this Form c, Action<Form> action)
        {
            if (c.InvokeRequired)
            {
                try { c.Invoke(new Action(() => action(c))); }
                catch { }
            }
            else
            {
                action(c);
            }
        }

然后打电话

frm.InvokeIfRequired((_)=>{frm.ChangeSomethingInTheUI();});

通过这种方式,您可以确定该操作将在正确的线程中执行。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    相关资源
    最近更新 更多