2014-05-08 52 views
1

我有一个显示另一个模态窗体(B)的模态窗体(A)。 B显示数据集并允许用户与之交互。我的问题是,一个动作要求A再次成为焦点形式,因此用户可以在不关闭B的情况下输入某些值。我尝试了A.BringToFront和A.SetFocus,它确实显示在前面,但输入焦点仍然在B当你点击你不应该的地方时,A中的任何点击或类似的操作都会导致窗口“叮当”。代码有点像在Delphi中切换模态窗体

A.ShowModal; 。 。 。在A的事件中: B.ShowModal(); 。 。 。在事件B中:

someobject.someMethodThatRequiresAFocused;

我的猜测是,一些模糊和奇怪的API调用可能会使A模式再次¿任何想法?

问候

+0

唯一不明白的地方在于你的代码:-)不,只是在开玩笑。但这就是模态的工作原理,以及为什么它被称为“模态”。你想要的是一个非模态窗口。 – JensG

+0

为什么不把所有东西放在一个表格上?您可以使用pagecontrol分开该部分。你甚至可以以编程方式在页面之间切换。 – Johan

回答

5

当显示模式窗体,包括其他模式窗体所有当前可见的形式被禁用。因此,不可能在多种模态形式之间切换。您需要重新考虑您的UI设计,以便B不会回到A以获得新的输入。至少,您可以让B打开一个新的模式窗体C,它提示用户输入所需的值并将它们输入B,然后BC可以用新值更新A

3

没有API在窗口之间切换模态。无论如何,你正在寻找你的案例的API是EnableWindow。这就是模式的工作方式,除了用户应该使用的窗口以外的其他窗口都被禁用,以至于他/她无法与其进行交互。这也是“叮叮当当”的原因,向用户提供反馈。

因此,尽管让用户使用已被禁用的窗口来支持另一个模式窗口在技术上很简单,但处理状态可能并不简单。下面我将举一个最低限度的例子来说明它看起来会如何。

'FormB'第一个。让我们假设你在'Owner'参数中传递'FormA'的引用,而'FormA'正在构造'FormB'。下面的是什么,应该让“模拟”再次莫代尔可能看起来像代码:

procedure TFormB.BtnMakeFormAModalAgainClick(Sender: TObject); 
begin 
    Enabled := False;     // so that 'A' will behave like it's modal 
    EnableWindow(TFormA(Owner).Handle, True); // so that 'A' could be interacted 
    TFormA(Owner).SetFocus; 
end; 

运行此代码时,会发生什么是“模拟”被启用并带到面前,“FormB”被禁用 - 点击时会产生一个'丁'。

但是我们还没有完成。因为我们修改了模态的含义 - 现在我们不希望'FormA'在用户完成时关闭。以下是如何在“形式上的单位代码可能看起来像:

type 
    TFormA = class(TForm) 
    BtnShowModalB: TButton; 
    BtnOk: TButton; 
    procedure BtnShowModalBClick(Sender: TObject); 
    procedure BtnOkClick(Sender: TObject); 
    private 
    FModalB: TForm; 
    end; 

implementation 

uses 
    unitOfFormB; 

{$R *.dfm} 

procedure TFormA.BtnShowModalBClick(Sender: TObject); 
begin 
    FModalB := TFormB.Create(Self); // so that FormB can find FormA from the Owner 
    FModalB.ShowModal; 
    FModalB.Free; 
    FModalB := nil; // Need this if we're going to decide if FormB is showing 
        // by testing against this reference 
end; 

procedure TFormA.BtnOkClick(Sender: TObject); 
begin 
    if Assigned(FModalB) then begin // is FormB the actual modal form? 
    EnableWindow(Handle, False); // disable this form so it would 'ding' 
    FModalB.Enabled := True;  // enable FormB, so user can interact with it 
    FModalB.SetFocus; 
    ModalResult := mrNone;  // don't close, FormB is the first one to be closed 
    end else 
    ModalResult := mrOk; 
end; 


我几乎肯定的,这个例子是不完整的,但这里的,你要寻找的API。