I have a form.
我有一个形式。
In that form I create an instance of a class on a new thread because it runs some long running logic. The form also gives the user the ability to cancel this logic/thread.
在这种形式下,我在一个新线程上创建一个类的实例,因为它运行一些长期运行的逻辑。表单还允许用户取消此逻辑/线程。
That class opens a new form if input is required.
如果需要输入,该类将打开一个新表单。
The new form sometimes appears behind the other form.
这种新形式有时出现在另一种形式的后面。
I set a property on the class:
我在类上设置了一个属性:
public Form ParentForm{get;set;}
I can now do:
我现在可以做的事:
MyForm form = new MyForm();
form.ShowDialog(ParentForm);
However I get a cross thread exception when calling ShowDialog(ParentForm)
.
但是,在调用ShowDialog(ParentForm)时,会得到一个跨线程异常。
I know I can use InvokeRequired
somehow but not sure how on a property.
我知道我可以使用InvokeRequired但不知道如何使用属性。
Thanks
谢谢
UPDATE: Have tried doing this but still get exception:
更新:尝试过这样做,但仍然有例外:
MyForm form = new MyForm();
form.ShowDialog(GetParentForm());
private Form GetParentForm()
{
//You have to Invoke() so you can wait for the function to return and obtain its return value.
if (ParentForm.InvokeRequired)
{
return (Form)ParentForm.Invoke(new Func<Form>(() => GetParentForm()));
}
else
{
return ParentForm;
}
}
2 个解决方案
#1
1
Your updated method (GetParentForm
) won't work because you're wrapping the task of getting the reference to ParentForm
in an InvokeRequired
block. You could try wrapping the ShowDialog
call in such a block instead, but I think you would still get the cross-threading error.
更新后的方法(GetParentForm)无法工作,因为您正在包装在InvokeRequired块中获取对ParentForm的引用的任务。您可以尝试在这样的块中包装ShowDialog调用,但是我认为您仍然会得到交叉线程错误。
Your simplest fix would be to move the code that creates and shows the second form out of your class and into ParentForm
. So instead of this:
最简单的解决方案是将创建并显示第二种形式的代码从类中移到ParentForm中。而不是:
MyForm form = new MyForm();
form.ShowDialog(ParentForm);
you would do this:
你会这样做:
ParentForm.showMyNewForm();
and in ParentForm
you would have this:
父母的形式是这样的
public void showMyNewForm()
{
MyForm form = new MyForm();
form.ShowDialog(this);
}
If MyForm
needs to have a reference to the class on the other thread, you would just add a parameter to showMyNewForm()
so that the reference to it can be passed in.
如果MyForm需要对另一个线程上的类有引用,那么只需向showMyNewForm()添加一个参数,以便可以传入对它的引用。
What you're trying to do here (creating and showing related, connected forms that are created on different threads) is really going against the grain of how forms are meant to be used in .NET.
您在这里尝试做的(创建和显示在不同线程上创建的相关的、连接的表单)实际上与. net中使用表单的方式背道而驰。
#2
0
you can add async method to a form. Let's say like this:
您可以将异步方法添加到表单中。假设是这样的:
public class MyForm : Form
{
public void ShowModalAsync()
{
this.Invoke(new Action(()=> {
ShowDilaog(..);
}));
}
}
and use this, like:
和使用,如:
MyForm form = new MyForm();
form.ShowModalAsync(...);
Should work for you.
应该为你工作。
By the way, if your problem is only the fact that the window appears on bihind of others, try to make use of Form.TopMost property setting it to true
. Having in mind that it, yes, will bring it infront of other forms, but not necessary infront of other topmost forms.
顺便说一下,如果你的问题只是窗口出现在别人的后面,那就试着利用形式。最高属性设置为true。记住,是的,它会把它放在其他形式前面,但不是必须放在最上面的形式前面。
#1
1
Your updated method (GetParentForm
) won't work because you're wrapping the task of getting the reference to ParentForm
in an InvokeRequired
block. You could try wrapping the ShowDialog
call in such a block instead, but I think you would still get the cross-threading error.
更新后的方法(GetParentForm)无法工作,因为您正在包装在InvokeRequired块中获取对ParentForm的引用的任务。您可以尝试在这样的块中包装ShowDialog调用,但是我认为您仍然会得到交叉线程错误。
Your simplest fix would be to move the code that creates and shows the second form out of your class and into ParentForm
. So instead of this:
最简单的解决方案是将创建并显示第二种形式的代码从类中移到ParentForm中。而不是:
MyForm form = new MyForm();
form.ShowDialog(ParentForm);
you would do this:
你会这样做:
ParentForm.showMyNewForm();
and in ParentForm
you would have this:
父母的形式是这样的
public void showMyNewForm()
{
MyForm form = new MyForm();
form.ShowDialog(this);
}
If MyForm
needs to have a reference to the class on the other thread, you would just add a parameter to showMyNewForm()
so that the reference to it can be passed in.
如果MyForm需要对另一个线程上的类有引用,那么只需向showMyNewForm()添加一个参数,以便可以传入对它的引用。
What you're trying to do here (creating and showing related, connected forms that are created on different threads) is really going against the grain of how forms are meant to be used in .NET.
您在这里尝试做的(创建和显示在不同线程上创建的相关的、连接的表单)实际上与. net中使用表单的方式背道而驰。
#2
0
you can add async method to a form. Let's say like this:
您可以将异步方法添加到表单中。假设是这样的:
public class MyForm : Form
{
public void ShowModalAsync()
{
this.Invoke(new Action(()=> {
ShowDilaog(..);
}));
}
}
and use this, like:
和使用,如:
MyForm form = new MyForm();
form.ShowModalAsync(...);
Should work for you.
应该为你工作。
By the way, if your problem is only the fact that the window appears on bihind of others, try to make use of Form.TopMost property setting it to true
. Having in mind that it, yes, will bring it infront of other forms, but not necessary infront of other topmost forms.
顺便说一下,如果你的问题只是窗口出现在别人的后面,那就试着利用形式。最高属性设置为true。记住,是的,它会把它放在其他形式前面,但不是必须放在最上面的形式前面。