如何关闭“;输入“;在UWP中

本文关键字:UWP 输入 何关闭 | 更新日期: 2023-09-27 18:26:13

我一直在尝试获得一个带有TextBox的简单ContentDialog,当用户在TextBox中点击Enter时关闭。遗憾的是,即使ContentDialog响应Esc,如果没有TextBox,它也无法工作。

我希望有一种方法可以从TextBoxKeyDown处理程序内部设置Result,但ContentDialog似乎缺少这一点?!

如何关闭“;输入“;在UWP中

您可以在TextBox KeyDown处理程序中使用Hide()方法关闭ContentDialog,简单示例:

ContentDialog c = new ContentDialog();
var tb = new TextBox();
tb.KeyDown += (sender, args) =>
{
     if (args.Key == VirtualKey.Enter)
     {
          c.Hide();
     }
};
c.Content = tb;
c.ShowAsync();

编辑:但是,当您想在没有TextBox的情况下关闭对话框时,情况似乎会更复杂。您必须订阅全球Window.Current.CoreWindow.KeyDown活动:

ContentDialog c = new ContentDialog();
Window.Current.CoreWindow.KeyDown += (sender, args) =>
{
      if (args.VirtualKey == VirtualKey.Enter)
      {
            c.Hide();
      }
};
c.ShowAsync();

这是我的最终解决方案,它将在输入上为我提供ContentDialogResult.Primary

我将此添加到我的ContentDialog:

    public new IAsyncOperation<ContentDialogResult> ShowAsync()
    {
        var tcs = new TaskCompletionSource<ContentDialogResult>();
        CaptionTB.KeyDown += (sender, args) =>
        {
            if (args.Key != VirtualKey.Enter) return;
            tcs.TrySetResult(ContentDialogResult.Primary);
            Hide();
            args.Handled=true;
        };
        var asyncOperation = base.ShowAsync();
        asyncOperation.AsTask().ContinueWith(task => tcs.TrySetResult(task.Result));
        return tcs.Task.AsAsyncOperation();
    }

不幸的是,ShowAsync不是虚拟的,所以我不得不new这个函数。不过对我来说效果很好!

简单的答案是,如果没有保留识别按下哪个按钮功能的变通方法和技巧,这是不可能的。长期的答案是,幸运的是,ContentDialog的子类可以非常干净和容易地完成我们想要的事情:

using System;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
namespace NeoSmart.Dialogs
{
    class HotkeyContentDialog : ContentDialog
    {
        public new event TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> PrimaryButtonClick;
        public new event TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> SecondaryButtonClick;
        public ContentDialogResult Result { get; set; }
        public new async Task<ContentDialogResult> ShowAsync()
        {
            var baseResult = await base.ShowAsync();
            if (baseResult == ContentDialogResult.None)
            {
                return Result;
            }
            return baseResult;
        }
        protected override void OnKeyUp(KeyRoutedEventArgs e)
        {
            if (e.Key == Windows.System.VirtualKey.Enter)
            {
                Result = ContentDialogResult.Primary;
                PrimaryButtonClick?.Invoke(this, default(ContentDialogButtonClickEventArgs));
                Hide();
            }
            else if (e.Key == Windows.System.VirtualKey.Escape)
            {
                Result = ContentDialogResult.Secondary;
                SecondaryButtonClick?.Invoke(this, default(ContentDialogButtonClickEventArgs));
                Hide();
            }
            else
            {
                base.OnKeyUp(e);
            }
        }
    }
}

只要使用HotkeyContentDialog而不是ContentDialog,一切都会好起来的。

自从提出这个问题以来已经有一段时间了,但ContentDialog有一个DefaultButton属性,可以按照您想要的方式处理Enter。

内容对话框默认按钮

对于TextBox,我认为您必须将AcceptsReturn属性设置为false,因为这可能会干扰用于关闭对话框的Enter。

文本框接受返回

Mahmouds解决方案非常完美!应该被接受作为答案IMO。这是我进一步修改的HotkeyContentDialog类:

public class HotkeyContentDialog : ContentDialog
{
    public new event TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> PrimaryButtonClick;
    public new event TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> SecondaryButtonClick;
    public ContentDialogResult Result { get; set; }
    public new async Task<ContentDialogResult> ShowAsync()
    {
        var baseResult = await base.ShowAsync();
        return baseResult == ContentDialogResult.None ? Result : baseResult;
    }
    protected override void OnKeyUp(KeyRoutedEventArgs e)
    {
        switch (e.Key)
        {
            case Windows.System.VirtualKey.Enter:
                Result = ContentDialogResult.Primary;
                PrimaryButtonClick?.Invoke(this, default);
                Hide();
                break;
            case Windows.System.VirtualKey.Escape:
                Result = ContentDialogResult.Secondary;
                SecondaryButtonClick?.Invoke(this, default);
                Hide();
                break;
            default:
                base.OnKeyUp(e);
                break;
        }
    }
}