我正在尝试创建密码内容对话框,但我不想使用内置对话框结果,因为它似乎有限。例如,我希望用户能够按 Enter 键来代替单击主按钮,并且如果在有人按 Enter 时关闭对话框,我似乎无法从对话框中获得结果。
我尝试模仿此处的答案WinUI 3:在ContentDialog打开时以编程方式更改ContentDialog大小用于创建自定义对话框结果,但使用内容对话框而不是窗口。我不想为这么小的对话框使用窗口。我更喜欢内置内容对话框。
我的代码如下,但我在线上收到堆栈溢出错误:_taskCompletionSource = new();
本质上,我想控制内容对话框的对话框结果,特别是在按下 Enter 键时关闭对话框时。因此,任何实现这一目标的解决方案都将受到赞赏,包括修复下面代码中的方法。
public sealed partial class PasswordDia : ContentDialog
{
protected TaskCompletionSource<ContDialogResult>? _taskCompletionSource;
public static ContDialogResult DialogResult = ContDialogResult.None;
public enum ContDialogResult
{
None,
Cancel,
OK,
}
public PasswordDia()
{
this.InitializeComponent();
this.IncorrectPinTextBlock.Visibility = Visibility.Collapsed;
this.Closed += ContentDialog_Closed;
}
private void ContentDialog_Closed(ContentDialog sender, ContentDialogClosedEventArgs e)
{
_taskCompletionSource?.SetResult(DialogResult);
}
public Task<ContDialogResult> ShowAsync()
{
_taskCompletionSource = new();
this.ShowAsync();
return _taskCompletionSource.Task;
}
private async void Ok_Click(object sender, RoutedEventArgs e)
{
if (this.AdminPasswordBox.Password == ConfigurationManager.AppSettings["AdminPassword"].ToString())
{
DialogResult = ContDialogResult.OK;
this.Hide();
}
else
{
this.IncorrectPinTextBlock.Visibility = Visibility.Visible;
}
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
DialogResult = ContDialogResult.Cancel;
this.Hide();
}
}
恕我直言,你不需要
TaskCompletionSource
。这是一个简单的例子:
public sealed partial class PasswordDialog : ContentDialog
{
public PasswordDialog() : base()
{
StackPanel content = new();
UserIdControl = new TextBox();
PasswordControl = new PasswordBox();
content.Children.Add(UserIdControl);
content.Children.Add(PasswordControl);
this.Content = content;
this.Closed += ContentDialog_Closed;
}
public enum ContDialogResult
{
None,
Cancel,
OK,
}
public ContDialogResult DialogResult { get; private set; } = ContDialogResult.None;
public string UserId { get => UserIdControl.Text; }
public string Password { get => PasswordControl.Password; }
private TextBox UserIdControl { get; set; }
private PasswordBox PasswordControl { get; set; }
private void ContentDialog_Closed(ContentDialog sender, ContentDialogClosedEventArgs e)
{
if (e.Result == ContentDialogResult.Primary &&
PasswordControl.Password == "1234")
{
DialogResult = ContDialogResult.OK;
return;
}
DialogResult = ContDialogResult.Cancel;
}
}
var dialog = new PasswordDialog()
{
Title = "Admin Password",
PrimaryButtonText = "OK",
CloseButtonText = "Cancel",
XamlRoot = this.XamlRoot,
};
await dialog.ShowAsync();
if (dialog.DialogResult == PasswordDialog.ContDialogResult.OK)
{
System.Diagnostics.Debug.WriteLine("Login successed.");
return;
}
System.Diagnostics.Debug.WriteLine($"Login failed. [UserId: {dialog.UserId}, Password: {dialog.Password} ]");
顺便说一句,你的代码不起作用,因为
this.ShowAsync()
会调用它 self。我猜你的意思是base.ShowAsync()
。