Flex Alert 控件:激活“默认”警报输入/空格键上的按钮

发布于 2024-08-15 00:41:56 字数 1557 浏览 4 评论 0原文

无论我尝试什么,我似乎都无法触发 Flex 3.4 应用程序中警报控件中“默认”按钮的单击事件。

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 指定“默认”选项(来自第三个参数中的按位列表)是“是”按钮。理论上,根据我设计 Windows 应用程序的经验,“默认按钮”意味着按 Enter 键(或有时按空格键)会触发该按钮的单击事件。

如果很重要,则相关警报是模态的。

我可以看到该按钮的样式是默认的:与“取消”按钮相比,或者在将 null 作为最后一个参数传递时与自身相比,它会出现一点光环或额外的边框。

然而,按 Enter 和 Space 键似乎没有任何影响。我是否做错了什么,或者错过了让此功能发挥作用的一些关键步骤?


2010-02-17 更新:

基于我对 @rhtx 的回答的第二条评论:

好吧,终于开始尝试这个了。由于 Alert 类使用了大量静态方法,因此我基本上只是将 Alert 和 AlertForm 类复制到我的项目中(并修复了包含的一些相对路径),而我最终得到的是一个更丑陋的警报框,它可以工作(或不能工作) ,取决于您的观点)与普通警报类相同。然而,我确实意识到,如果您按 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);

我还发现 这篇博文 并尝试这样做来集中 alertForm

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

这些都没有引发错误,但也没有产生所需的结果。

No matter what I try, I can't seem to fire the click event on the "default" button in an Alert control in a Flex 3.4 application.

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

In the above code sample, the final argument: Alert.YES is specifying that the "default" option (from the bitwise list in the 3rd argument) is the "Yes" button. In theory, and based on my experience designing Windows applications, "default button" means that hitting the enter key (or sometimes the space bar) fires the click event for that button.

If it matters, the Alert in question is modal.

I can see that the button is styled as the default: it gets a bit of a halo or extra border when compared to the Cancel button or when compared to itself when passing null as the last argument.

However, hitting the enter and space keys seem to have no affect. Am I doing something wrong, or missing some crucial step in getting this functionality to work?


Update 2010-02-17:

Based on my 2nd comment on @rhtx's answer:

Ok, finally got around to trying this. Since the Alert class uses lots of static methods, I essentially just copied the Alert and AlertForm classes into my project (and fixed some relative paths for includes), and what I ended up with was an uglier alert box that works (or doesn't, depending on your perspective) the same way as the vanilla Alert class. I did realize, however, that if you hit TAB it will focus the alert buttons, at which point hitting Escape/Enter will have the desired effect... So how do I eliminate the need to hit TAB?

I tried a few more things and didn't get anywhere.

I tried faking a TAB keypress after opening the alert (with both KEY_DOWN and KEY_UP event types):

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);

I also found this blog post and tried doing this to focus the alertForm:

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

Neither of these threw errors, but neither produced the desired result, either.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅唱ヾ落雨殇 2024-08-22 00:41:56

我将通过扩展 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 功能”的信息,但我会尝试稍后再发布一些相关内容。希望这一点有帮助。

另外 - 我不是 100% 同意 - 但我认为您需要在删除警报弹出窗口时手动删除事件侦听器。

Aaand...您可能不需要这两个听众。现在无法测试来确定。

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

经过更多的观察,也许最好的方法是扩展 AlertForm 类(它管理警报的按钮),然后扩展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 方法,并为“是”按钮传入适当的字符串值。

作为参考,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);

}

I would approach this by extending the Alert class to include functionality that listens for keyUp events from the Enter and Space keys.

In the createChildren method of your subclass:

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...
    }
}

I'm having some issues with my set up this morning and can't get into the Alert class to provide info on how to "Trigger the Alert.YES functionality", but I'll try to post some more on this later on. Hope this little bit helps.

Also - I'm not 100% on this - but I think you will need to manually remove the event listeners when the Alert popup is removed.

Aaand... you may not need both of those listeners. Can't test right now to make sure.

UPDATE: -----------------

After a little more looking, maybe the best way to go about this is to extend the AlertForm class (which manages the Alert's buttons), and then extend the Alert class to use your extended AlertForm class.

The AlertForm class has a keyDownHandler method, which it defines like this:

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");
    }
}

You can see that it is setting up the 'close' behavior in response to pressing the Escape key. You add a little logic, based on the code in the above 'keyUpListener' function to make a call to the AlertForm's removeAlert method, passing in the appropriate String value for the Yes button.

For reference, the removeAlert method looks like this:

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);

}
心房的律动 2024-08-22 00:41:56

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

(1) 在 Alert.show() 中定义默认按钮,(2) 使用 callLater(),以及 (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 键的作用就像用户用鼠标单击了默认按钮一样。

I ran into a similar situation. What got me out of it was:

(1) defining the default button in Alert.show(), (2) using a callLater(), and (3) setting the focus manually on the default button.

For example, using Alert.CANCEL as the intended default button (can change to Alert.YES if needed):

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();
}

This enables the Escape and Enter keys to act as if the user clicked the default button with the mouse.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文