如何关闭“;输入“;在UWP中
本文关键字:UWP 输入 何关闭 | 更新日期: 2023-09-27 18:26:13
我一直在尝试获得一个带有TextBox
的简单ContentDialog
,当用户在TextBox
中点击Enter时关闭。遗憾的是,即使ContentDialog响应Esc,如果没有TextBox
,它也无法工作。
我希望有一种方法可以从TextBox
的KeyDown
处理程序内部设置Result,但ContentDialog
似乎缺少这一点?!
您可以在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;
}
}
}