动态创建工具条形菜单项时出错



>我遇到了以下问题:我有一个配置文件和一个侦听器。更改时,会触发修改toolStripMenuItem的方法 (createMenuAndItems(。

createMenuAndItems方法在加载窗体时和修改配置文件时调用。每当数组

strArrays = new string[] { "Copy File" ,  "Exit"};

有多个项目,修改配置文件时显示错误。 加载表单时工作正常。

错误如Visual Studio中所示:

System.InvalidOperationException is unhandling

HResult=-2146233079
Message=:跨线程操作无效:控制"topMenu"从创建它的线程以外的线程访问

实际消息是

Message=Operación no válida a través de subprocesos: Se tuvo acceso al control 'topMenu' desde un subproceso distinto a aquel en que lo creó.

Source=System.Windows.Forms
StackTrace:

尝试了CheckForIllegalCrossThreadCalls = False;但没有运气

奇怪的是,如果数组strArrays只有一个值,它就像一个魅力。 但是当添加更多项目时开始显示此错误

这是代码。

文件上的侦听器:

private void configWatcher()
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher()
{
Path = string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "\Launcher"),
Filter = "Config.xml"
};
fileSystemWatcher.Changed += new FileSystemEventHandler(this.createMenuAndItems);
fileSystemWatcher.EnableRaisingEvents = true;
}

下面是创建和修改toolStripMenuItem的代码

private void createMenuAndItems()
{
string str;
ToolStripMenuItem toolStripMenuItem;
int i;
base.Invoke(new Action(() =>
{
base.Controls.Find("topMenu", false);
if (base.Controls.IndexOfKey("topMenu") > 0)
{
base.Controls.RemoveByKey("topMenu");
}
}));
MenuStrip menuStrip = new MenuStrip()
{
Name = "topMenu"
};
base.Invoke(new Action(() => this.Controls.Add(menuStrip)));
string[] strArrays = new string[] { "Menú" };
string[] array = strArrays;
for (i = 0; i < (int)array.Length; i++)
{
ToolStripMenuItem toolStripMenuItem1 = new ToolStripMenuItem(array[i]);
menuStrip.Items.Add(toolStripMenuItem1);
}
foreach (ToolStripMenuItem item in menuStrip.Items)
{
if (item.Text == "Menú")
{
strArrays = new string[] { "Copy File" ,  "Exit"};
array = strArrays;                    
for (i = 0; i < (int)array.Length; i++)
{
str = array[i];
toolStripMenuItem = new ToolStripMenuItem(str, null, new EventHandler(this.ChildClick));
item.DropDownItems.Add(toolStripMenuItem);
}
foreach (ToolStripMenuItem dropDownItem in item.DropDownItems)
{
if (dropDownItem.Text == "Copy File")
{
//gives a list of strings.
array = this.fetchServersFromConfig().ToArray();
for (i = 0; i < (int)array.Length; i++)
{
str = array[i];
toolStripMenuItem = new ToolStripMenuItem(string.Concat("Origin: ", str), null, new EventHandler(this.copyFile));
dropDownItem.DropDownItems.Add(toolStripMenuItem);
}
}
if (dropDownItem.Text == "Exit")
{                            
dropDownItem.ShortcutKeys = Keys.Control | Keys.Q;
dropDownItem.Click += new EventHandler(this.exitButtonMenu);
}
}
}
}
}

谢谢!

最后通过configWatcher()内的主线程调用菜单和项目的创建来解决这个问题

喜欢这个:

fileSystemWatcher.Changed += new FileSystemEventHandler(base.Invoke(new Action(() => this.createMenuAndItems())););

而不是:

fileSystemWatcher.Changed += new FileSystemEventHandler(this.createMenuAndItems);

相关内容

  • 没有找到相关文章

最新更新