Flex Alert控制:激活输入/空格键按下的“默认”按钮

时间:2009-12-17 16:44:53

标签: flex actionscript-3 flex3 adobe

无论我尝试什么,我似乎无法在Flex 3.4应用程序的Alert控件中的“默认”按钮上触发click事件。

Alert.show(
    'Are you sure you want to delete the selected link?',
    'Confirm Delete',
    Alert.YES | Alert.CANCEL,
    null, 
    confirmDelete, 
    null, 
    Alert.YES
);

在上面的代码示例中,最后一个参数:Alert.YES指定“default”选项(来自第三个参数中的按位列表)是“Yes”按钮。从理论上讲,根据我设计Windows应用程序的经验,“默认按钮”意味着按下回车键(或有时是空格键)会触发该按钮的click事件。

如果重要,有问题的警报是模态的。

我可以看到按钮被设置为默认设置:与“取消”按钮相比,它会获得一点光环或额外边框,或者在将null作为最后一个参数传递时与自身进行比较。

但是,点击输入和空格键似乎没有任何影响。我做错了什么,或者错过了使这项功能起作用的一些关键步骤?


更新2010-02-17:

基于我对@ rhtx答案的第二次评论:

  

好的,终于开始尝试这个了。由于Alert类使用了许多静态方法,我基本上只是将Alert和AlertForm类复制到我的项目中(并修复了包含的一些相对路径),而我最终得到的是一个可行的(或不是)的丑陋警报框,取决于您的观点)与vanilla Alert类相同。然而,我确实意识到,如果你点击TAB,它将聚焦警报按钮,此时点击Escape / Enter将产生预期的效果......那么我如何消除点击TAB的需要?

我尝试了一些其他的东西并没有到达任何地方。

我在打开警报后尝试伪造TAB按键(同时使用KEY_DOWN和KEY_UP事件类型):

var a:Alert = Alert.show(msg, title, Alert.YES | Alert.CANCEL, null, fnCb);
var tabEvent:KeyboardEvent = new KeyboardEvent(
    KeyboardEvent.KEY_DOWN,
    true,
    false, 
    0,
    Keyboard.TAB
);
a.dispatchEvent(tabEvent);

我还找到了this blog post并尝试这样做以关注alertForm

var a:Alert = Alert.show(msg, title, Alert.YES | Alert.CANCEL, null, fnCb);
a.mx_internal::alertForm.setFocus();

这些都没有引起错误,但也没有产生预期的结果。

2 个答案:

答案 0 :(得分:1)

我会通过将Alert类扩展为包含从Enter和Space键侦听keyUp事件的功能来实现此目的。

在子类的createChildren方法中:

override public function createChildren():void
{
    super.createChildren();
    this.addEventListener(KeyboardEvent.KEY_UP, keyUpListener);
    this.stage.addEventListener(KeyboardEvent.KEY_UP, keyUpListener);
}

private function keyUpListener(e:KeyboardEvent):void
{
    if(e.keyCode == Keyboard.ENTER || e.keyCode == Keyboard.SPACE)
    {
        //Trigger the Alert.YES functionality...
    }
}

今天早上我的设置存在一些问题,无法进入Alert类提供有关如何“触发Alert.YES功能”的信息,但我会尝试在此上发布更多内容稍后的。希望这有点帮助。

另外 - 我不是百分之百 - 但我认为你需要在删除警告弹出窗口时手动删除事件监听器。

Aaand ......你可能不需要这两个听众。现在无法测试以确保。

更新:-----------------

再看一下,也许最好的方法是扩展AlertForm类(管理Alert的按钮),然后扩展Alert类以使用扩展的AlertForm类。

AlertForm类有一个keyDownHandler方法,它定义如下:

override protected function keyDownHandler(event:KeyboardEvent):void
{
    var buttonFlags:uint = Alert(parent).buttonFlags;

    if (event.keyCode == Keyboard.ESCAPE)
    {
        if ((buttonFlags & Alert.CANCEL) || !(buttonFlags & Alert.NO))
            removeAlert("CANCEL");
        else if (buttonFlags & Alert.NO)
            removeAlert("NO");
    }
}

您可以看到它正在设置“关闭”行为以响应按Escape键。根据上面'keyUpListener'函数中的代码添加一点逻辑,以调用AlertForm的removeAlert方法,为Yes按钮传入适当的String值。

作为参考,removeAlert方法如下所示:

private function removeAlert(buttonPressed:String):void
{
    var alert:Alert = Alert(parent);

    alert.visible = false;

    var closeEvent:CloseEvent = new CloseEvent(CloseEvent.CLOSE);
    if (buttonPressed == "YES")
        closeEvent.detail = Alert.YES;
    else if (buttonPressed == "NO")
        closeEvent.detail = Alert.NO;
    else if (buttonPressed == "OK")
        closeEvent.detail = Alert.OK;
    else if (buttonPressed == "CANCEL")
        closeEvent.detail = Alert.CANCEL;
    alert.dispatchEvent(closeEvent);

    mx.managers.PopUpManager.removePopUp(alert);

}

答案 1 :(得分:0)

我遇到了类似的情况。让我摆脱困境的是:

(1)使用Alert.show()定义callLater()中的默认按钮,(2),以及(3)在默认按钮上手动设置焦点。

例如,使用Alert.CANCEL作为预期的默认按钮(如果需要,可以更改为Alert.YES):

var a:Alert = Alert.show(msg, title, Alert.YES | Alert.CANCEL, null, fnCb, null, Alert.CANCEL);
callLater(setAlertButtonFocus,[a]);
...
private function setAlertButtonFocus(a:Alert):void {
    a.mx_internal::alertForm.mx_internal::defaultButton.setFocus();
}

这使Escape和Enter键的行为就像用户用鼠标单击默认按钮一样。