WinUI 3 内容对话框的自定义对话框结果

问题描述 投票:0回答:1

我正在尝试创建密码内容对话框,但我不想使用内置对话框结果,因为它似乎有限。例如,我希望用户能够按 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();
    }

}
c# winui-3 dialogresult contentdialog
1个回答
0
投票

恕我直言,你不需要

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

© www.soinside.com 2019 - 2024. All rights reserved.