我正在尝试关闭一个当前具有外部线程焦点的窗体。问题是我无法通过简单地调用form.Focused来访问该属性,它会按预期抛出“InvalidOperationException:跨线程操作无效”。接下来我尝试在其上调用Invoke但它不能将Control.Focused识别为getter方法。这是当前的代码:
private void CloseFormWithFocus()
{
FormCollection openForms = Application.OpenForms;
Form closeThisForm = null;
foreach (Form f in openForms)
{
// Here's the part that does not compile
if (closeThisForm.Invoke((MethodInvoker)delegate () { closeThisForm.Focused; });)
{
closeThisForm = f;
}
}
}
然而令我困惑的是,另一个几乎相同的方法是通过与form.Name属性进行比较来关闭表单,这样我就可以像这样简单地调用它(可能不是线程安全的):
private void CloseForm(string formName)
{
FormCollection openForms = Application.OpenForms;
Form closeThisForm = null;
foreach (Form f in openForms)
{
if (f.Name == formName)
{
closeThisForm = f;
}
}
}
我已经四处寻找调用属性getter的不同方法,但是所有来源都只是声明编译器应该识别调用表单。聚焦为getter,现在我很难过。
如果form.Propertyname调用不起作用,从外部线程调用(如果可能的话只是简单读取)表单的属性值的正确方法是什么?
谢谢。
答案 0 :(得分:0)
Focused
属性并非“只是一个吸气剂”。
它将当前聚焦窗口与控件的Handle
属性进行比较。
Handle
属性首先检查跨线程访问
来自源代码:
public virtual bool Focused {
get {
return IsHandleCreated && UnsafeNativeMethods.GetFocus() == Handle;
}
}
public IntPtr Handle {
get {
if (checkForIllegalCrossThreadCalls &&
!inCrossThreadSafeCall &&
InvokeRequired) {
throw new InvalidOperationException(SR.GetString(SR.IllegalCrossThreadCall,
Name));
}
您可以像这样返回Invoke
的值:
f.Invoke(new Func<bool>(() => f.Focused))
注意:您使用closeThisForm
(虽然为空)而不是f
。