我有一个自定义消息框(基本上是winform),它弹出在调用表单的中心,如下所示:
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
MsgBox.Show(this, "asdsdfsdf");
}
}
这里我传递this
(Form1)作为MsgBox
的所有者。现在我知道了MsgBox表单的位置,因为我也在传递父表单(Form1
)。
但我需要这个自定义消息框来对齐自己(中心到父窗体),即使是从其他类调用的,例如
public class Computer
{
public void Do(int i)
{
MsgBox.Show(i.ToString());
}
}
这里的问题是我无法将父窗体的引用传递给MsgBox
类。所以在这里我无法定位自定义框。我希望MsgBox
类能够确定哪个是调用堆栈中的最后一个窗体类?
我试过这个:
public partial class MsgBox : Form
{
private void X()
{
StackTrace df = new StackTrace();
foreach (var item in df.GetFrames())
{
var type = item.GetMethod().DeclaringType;
if (type.BaseType == typeof(Form))
{
IWin32Window w = //how to get the form instance here??
//------------
break;
}
}
}
}
我确实触及了内部if子句;问题是我不知道如何从type
变量中获取表单实例或表单的IWin32Window句柄。。我能做些什么来获得类的实例本身,而不是类型吗?
大编辑:很抱歉,我犯了一个很大的错误,说获取父窗体的引用是将子窗体居中。我需要MsqBox实例中父窗体的句柄,因为它还可以做其他事情。简而言之,我需要子窗体中的父窗体,而不需要引用未传递的父窗体。有可能吗?
您可以尝试将MessageBox集中在Form.ActiveForm.上
解决方案:
- 在每个
MsgBox
类实例中保留私有Form Parent { get; private set; }
属性 - 创建
MsgBox.ActiveForm { get { .. } }
静态属性,该属性将拾取Form.ActiveForm
,如果其类型为MsgBox
,则返回其父级
MsgBox
类的静态特性:
public static Form ActiveForm
{
get
{
return Form.ActiveForm == null ? null :
Form.ActiveForm is MsgBox ? ((MsgBox)Form.ActiveForm).Parent :
Form.ActiveForm;
}
}
这是一种方法,谢谢@Joe:
public static Form GetLastForm()
{
if (Form.ActiveForm != null && !(Form.ActiveForm is MsgBox))
return Form.ActiveForm;
var openForms = Application.OpenForms.Cast<Form>().Where(f => !(f is MsgBox));
if (openForms.Count > 0)
return openForms[openForms.Count - 1];
return null;
}
我在通过堆栈跟踪方法获得正确的父窗体时遇到了问题。这里的基本困惑是确定我想要的是当前活动的表单,还是最后打开的表单,或者是导致MsgBox弹出的表单。这三种方法都可能不同,我选择了堆栈跟踪方法,以便获得第三种方法。依赖堆栈跟踪是令人沮丧的。我刚刚得到了活动表单,如果没有,我会检索最后打开的表单。Application.OpenForms
按照正确的顺序打开表单。