【发布时间】:2009-02-04 20:24:21
【问题描述】:
我刚刚发布了一个关于如何让代表更新另一个表单上的文本框的问题。就在我认为我使用 Invoke 得到答案的时候……这发生了。这是我的代码:
主窗体代码:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Data.OleDb;
using System.Collections.Specialized;
using System.Text;
using System.Threading;
delegate void logAdd(string message);
namespace LCR_ShepherdStaffupdater_1._0
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
public void add(string message)
{
this.Log.Items.Add(message);
}
public void logAdd(string message)
{ /////////////////////////// COMPILER ERROR BELOW ///////////
this.Invoke(new logAdd(add), new object[] { message }); // Compile error occurs here
}////////////////////////////// COMPILER ERROR ABOVE ///////////
private void exitProgramToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
{
Form aboutBox = new AboutBox1();
aboutBox.ShowDialog();
}
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void settingsToolStripMenuItem1_Click(object sender, EventArgs e)
{
settingsForm.settings.ShowDialog();
}
private void synchronize_Click(object sender, EventArgs e)
{
string message = "Here my message is"; // changed this
ErrorLogging.updateLog(message); // changed this
}
}
public class settingsForm
{
public static Form settings = new Settings();
}
}
日志类代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LCR_ShepherdStaffupdater_1._0
{
public class Logging
{
static Main mainClass = new Main();
static logAdd logAddDelegate;
public static void updateLog(string message)
{
logAddDelegate = mainClass.logAdd;
logAddDelegate(message);
}
}
}
-
编译错误:
InvalidOperationException 是 未处理 - Invoke 或 BeginInvoke 不能在控件上调用,直到 窗口句柄已创建。
我已经尝试在 Log 项上创建句柄...但是没有用。问题是我不知道自己在做什么,我在 Google 上广泛地进行了搜索,却只找到了模糊的答案。
请在我调用此委托之前告诉我如何创建句柄。当你在做的时候,给我一些方法可以让这个代码更简单。例如,我不想要两个 Add 函数……我必须这样做,因为我无法从 Logging 类中找到要调用的项目。有没有更好的方法来完成我需要做的事情?
谢谢!!!
编辑:
我的项目相当大,但这些是导致此特定问题的唯一项目。
Log 是我的 RichTextBox1 (Log.Items.Add(message)) 我将其重命名为 Log,以便重新输入。
我正在从不同的表单调用 updateLog(message)...让我在这里更新它(尽管我从它调用 updateLog(message) 并没有什么区别仍然给我这个错误)
你们将不得不让我的事情变得更简单......并提供示例。我不明白你们在这里所说的一切......我不知道如何使用方法和句柄的调用。我也研究过它的废话......
第二次编辑:
我相信我找到了问题所在,但不知道如何解决。
在我的日志记录类中,我使用此代码创建 mainClass:
静态 Main mainClass = new Main();
我正在为 Main() 创建一个全新的蓝图副本,包括 Log(我正在尝试更新的 Richtextbox)
当我调用 updateLog(message) 时,我相信我正在尝试更新 Main() 的第二个实体(也称为 mainClass)上的日志(richtextbox)。当然,这样做会抛出这个异常,因为我什至没有看到我正在使用的当前 Main 的副本。
这就是我的目标,感谢其中一位给出答案的人:
Main mainClass = Application.OpenForms.OfType<Main>().First();
logAddDelegate = mainClass.logAdd;
logAddDelegate(message);
我需要不使用 new() 运算符创建 mainClass,因为我不想创建表单的新蓝图,我希望能够编辑当前表单。
上面的代码不起作用,我什至找不到 Application.这甚至是 C# 语法吗?
如果我能让上面的代码工作,我想我可以解决我的问题,并在寻求答案几个小时后最终解决这个问题。
最终编辑:
感谢以下一位用户,我想通了。这是我更新的代码:
主窗体代码:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Data.OleDb;
using System.Collections.Specialized;
using System.Text;
using System.Threading;
delegate void logAdd(string message);
namespace LCR_ShepherdStaffupdater_1._0
{
public partial class Main : Form
{
private static Main mainFormForLogging;
public static Main MainFormForLogging
{
get
{
return mainFormForLogging;
}
}
public Main()
{
InitializeComponent();
if (mainFormForLogging == null)
{
mainFormForLogging = this;
}
}
public void add(string message)
{
this.Log.Items.Add(message);
}
public void logAdd(string message)
{
this.Log.BeginInvoke(new logAdd(add), new object[] { message });
}
private void exitProgramToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
{
Form aboutBox = new AboutBox1();
aboutBox.ShowDialog();
}
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void settingsToolStripMenuItem1_Click(object sender, EventArgs e)
{
settingsForm.settings.ShowDialog();
}
private void synchronize_Click(object sender, EventArgs e)
{
add("test");
Logging.updateLog("testthisone");
//DatabaseHandling.createDataSet();
}
}
public class settingsForm
{
public static Form settings = new Settings();
}
}
日志类代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LCR_ShepherdStaffupdater_1._0
{
public class Logging
{
static Main mainClass = Main.MainFormForLogging;
static logAdd logAddDelegate;
public static void updateLog(string message)
{
logAddDelegate = mainClass.logAdd;
logAddDelegate(message);
}
}
}
【问题讨论】:
-
您确定这是编译器错误吗?对我来说,这听起来更像是执行时间异常......
-
您确定 mainClass 与您正在查看的 Main 实例相同吗?您是否有可能有两个实例 - 一个已创建,一个未创建?
-
伙计们......我不确定自己......这部分让我很困惑,我几乎不知道发生了什么哈哈
-
“他的问题是我不知道我在做什么”...是的,这是个问题... :)
-
我让一件事开始工作,然后 5 分钟后又发生了其他事情。如果我能找到一个很好的例子,我会确切地知道某人在说什么。
标签: c# delegates invoke handle runtime-error