[英]How to close ContentDialog on "Enter" in UWP
I've been trying to get a simple ContentDialog
with a TextBox
to close when the user hits Enter while still in the TextBox
.我一直在尝试让一个带有
TextBox
的简单ContentDialog
在用户仍然在TextBox
点击Enter时关闭。 Sadly it doesn't even work without a TextBox
, even though the ContentDialog responds to Esc .遗憾的是,即使 ContentDialog 响应Esc ,它在没有
TextBox
情况下也无法工作。
I was hoping there was a way to set a Result from inside the KeyDown
Handler of the TextBox
, but it seems ContentDialog
lacks this?!我希望有一种方法可以从
TextBox
的KeyDown
处理程序内部设置 Result ,但似乎ContentDialog
缺少这个?!
You can close the ContentDialog using Hide()
method in TextBox
KeyDown
handler, simple example:您可以在
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();
EDIT: But it seems to be more complicated when you want to close the dialog without TextBox
.编辑:但是当您想在没有
TextBox
情况下关闭对话框时似乎更复杂。 You have to subscribe on global Window.Current.CoreWindow.KeyDown
event:您必须订阅全局
Window.Current.CoreWindow.KeyDown
事件:
ContentDialog c = new ContentDialog();
Window.Current.CoreWindow.KeyDown += (sender, args) =>
{
if (args.VirtualKey == VirtualKey.Enter)
{
c.Hide();
}
};
c.ShowAsync();
Here is my final solution that would get me a ContentDialogResult.Primary
on Enter这是我的最终解决方案,它可以让我在Enter 时获得
ContentDialogResult.Primary
I added this to my ContentDialog:我将此添加到我的 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();
}
unfortunately ShowAsync
isn't virtual so I had to new
the function.不幸的是
ShowAsync
不是虚拟的,所以我不得不new
这个函数。 It works well for me though!不过对我来说效果很好!
The short answer is that it isn't (cleanly) possible without workarounds and hacks that will preserve the functionality of identifying which button was pressed.简短的回答是,如果没有解决方法和黑客攻击,就不可能(完全)可能保留识别按下哪个按钮的功能。 The long answer is that it's fortunately very clean and easy to subclass
ContentDialog
to do exactly what we want:很长的答案是,幸运的是,将
ContentDialog
子类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);
}
}
}
}
Just use HotkeyContentDialog
instead of ContentDialog
and all will be well.只需使用
HotkeyContentDialog
而不是ContentDialog
一切都会好起来的。
It has been a while since this question has been asked, but a ContentDialog has a DefaultButton property that handles Enter in the way you want.自从提出这个问题以来已经有一段时间了,但是 ContentDialog 有一个 DefaultButton 属性,可以按照您想要的方式处理 Enter。
ContentDialog.DefaultButton ContentDialog.DefaultButton
For a TextBox, I assume you have to set the AcceptsReturn property to false because this may interfere with the Enter that is intended to close the dialog.对于 TextBox,我假设您必须将 AcceptsReturn 属性设置为 false,因为这可能会干扰旨在关闭对话框的 Enter。
Mahmouds solution is more than perfect! Mahmouds 解决方案非常完美! Should be accepted as answer IMO.
应该被接受为 IMO 的答案。 Here is the further reworked HotkeyContentDialog class from me:
这是我进一步重新设计的 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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.