在Delphi XE Update 1中,如果父(主)表单的FormStyle设置为fsStayOnTop,我将获得模态表单的看似随机的行为。
1)使用MainFormOnTaskbar:= False(旧方法),一切都"正常工作"。使用新的MainFormOnTaskbar:= True,当主窗体设置为"停留在顶部"时,模态窗体隐藏在主窗体后面。在大多数情况下说
modalForm.PopupParent := self;
就在调用modalForm之前。ShowModal似乎有所帮助。
2)我所有的模态表单都很简单,没有多余的装饰,位于MainFormCenter,不使用表单继承等。然而,PopupParent的修复只适用于其中的一半,而另一半仍然隐藏在主表单后面。最奇怪的是,在一种情况下,不相关的代码行的顺序会中断或使其中断。参见代码中的(1)和(2)行:
procedure TEchoMainForm.DBMaintenancePrompt( actions : TMaintenanceActions );
var
frm : TDBMaintenanceForm;
begin
frm := TDBMaintenanceForm.Create( self );
try
frm.Actions := actions; // (1)
frm.PopupParent := self; // (2)
frm.ShowModal;
finally
frm.Free;
end;
end;
按此顺序执行时,模态形式会正确地显示在主形式的顶部。但是当我反转行时,模态形式隐藏在main后面。标记为(1)的行设置了模态表单的属性,这导致TRzCheckGroup中的几个复选框被选中为未选中,位于TRzPageControl(来自Raize组件)上。这是上面第(1)行执行时运行的setter方法:
procedure TDBMaintenanceForm.SetActions(const Value: TMaintenanceActions);
var
ma : TMaintenanceAction;
begin
for ma := low( ma ) to high( ma ) do
cgMaintActions.ItemChecked[ ord( ma )] := ( ma in Value );
end;
end;
如果行(1)和(2)的顺序颠倒,这足以使情态形式显示在主形式后面。
这可能指向TRzCheckGroup(在setter代码运行时被操纵),但我有另外两个表单显示相同的问题,并且不使用TRzCheckGroup(或TRzPageControl)。我无法用使用Raize组件的单独示例应用程序重现这个问题。在setter期间禁用表单、页面控件或TRzCheckGroup是没有效果的。
这似乎不是一个时间问题,因为当模态形式显示隐藏一次,它总是这样做。行为的改变只来自于重新排列代码行。
3)最后一个观察:我的模态形式相当简单,所以它们几乎立即显示,没有明显的延迟。但是当主表单是fsStayOnTop时,我经常可以看到模态表单显示在它的顶部,然后看到它被"推"到后面。然后,按Esc键,(不可见的)模态表单显示在主表单的顶部几分之一秒,然后关闭。
要么是我错过了一些事后看来显而易见的东西,要么是这是对通灵调试的呼吁,我不知道。有什么想法吗?。我试着在另一种形式上找到问题发生的地方。它有几个按钮(Raize)和一个TSyntaxMemo(来自control .ru的一个增强的memo组件)。这种形式与遇到这个问题的其他形式几乎没有任何共同之处。在删除部分代码并进行测试之后,我现在可以通过在一个方法中做一个微小的更改来重现这个问题,该方法将一个字符串分配给memo组件:
这是我的原始代码,它导致包含编辑器的表单隐藏在主表单后面:
procedure TEditorForm.SetAsText(const Value: string);
begin
Editor.Text := Value;
end;
当我将赋值值更改为空字符串时,表单将正确显示:
procedure TEditorForm.SetAsText(const Value: string);
begin
Editor.Text := ''; // CRAZY! Problem goes away
end;
当我给编辑器分配一个字符时,表单又开始隐藏:
procedure TEditorForm.SetAsText(const Value: string);
begin
Editor.Text := 'a'; // Problem is back
end;
当然,其他两个有问题的表单不使用这个编辑器组件或它的任何单元。
我已经尝试删除备忘录控件并再次添加它(想想创建顺序等),但它没有效果。如果我用代码创建备忘录也是一样的。一旦将非空字符串分配给memo的Text属性,窗体就会隐藏。
我以前也遇到过同样的问题。我的解决方案是将Self.BringToFront;
添加到模态形式的OnShow
事件中。
Windows不支持很多应用程序的topmost表单,modal form默认是topmost。但是您可以在自己的表单中使用这种样式。
一个决定:删除你的主要形式的顶部大部分(不可见的效果),调用模态形式,设置回顶部样式当模态完成