You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现UserControl的异步等待?替代ContentDialog获取返回结果

给UserControl实现类似ContentDialog的ShowAsync异步等待方法

我完全懂你的需求——虽然ContentDialog能搞定这类弹窗任务,但有时候就是想自己用UserControl来实现,还得支持异步等待用户操作完成,拿到结果再继续后续逻辑。下面给你一个直接能用的实现方案:

步骤1:给LoginUserControl添加异步等待逻辑

我们需要在LoginUserControl里加入TaskCompletionSource来控制异步任务的完成,再封装一个ShowAsync方法,把UserControl放到Popup里显示(Popup是UWP原生的弹窗容器,完全符合你的需求)。

LoginUserControl的XAML(示例)

先写个简单的登录界面,包含密码框和操作按钮:

<UserControl
    x:Class="YourNamespace.LoginUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    d:DesignHeight="300"
    d:DesignWidth="400">
    <Grid Background="White" Padding="20" CornerRadius="8" BorderBrush="#E0E0E0" BorderThickness="1">
        <StackPanel>
            <TextBlock Text="请输入密码" Margin="0,0,0,10" FontSize="16"/>
            <PasswordBox x:Name="PasswordBox" PlaceholderText="输入密码" FontSize="14"/>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,20,0,0">
                <Button x:Name="CancelBtn" Content="取消" Margin="0,0,10,0" Padding="12,6"/>
                <Button x:Name="LoginBtn" Content="登录" Padding="12,6" Background="#0078D4" Foreground="White"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</UserControl>

LoginUserControl的后台代码

核心逻辑在这里,用TaskCompletionSource实现异步等待:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.Threading.Tasks;

namespace YourNamespace
{
    public sealed partial class LoginUserControl : UserControl
    {
        private TaskCompletionSource<bool> _taskCompletionSource;
        // 对外暴露输入的密码
        public string EnteredPassword => PasswordBox.Password;

        public LoginUserControl()
        {
            this.InitializeComponent();
            // 绑定按钮点击事件
            LoginBtn.Click += OnLoginClicked;
            CancelBtn.Click += OnCancelClicked;
        }

        // 封装ShowAsync方法,返回Task<bool>表示用户是否点击了登录
        public Task<bool> ShowAsync()
        {
            _taskCompletionSource = new TaskCompletionSource<bool>();

            // 创建Popup容器来承载UserControl
            var popup = new Popup
            {
                IsLightDismissEnabled = false, // 禁止点击外部关闭,必须手动操作按钮
                Child = this,
                Width = this.Width,
                Height = this.Height
            };

            // 设置Popup在屏幕居中显示
            var windowBounds = Window.Current.Bounds;
            popup.HorizontalOffset = (windowBounds.Width - this.Width) / 2;
            popup.VerticalOffset = (windowBounds.Height - this.Height) / 2;

            // 显示Popup
            popup.IsOpen = true;

            // 任务完成后清理Popup资源
            _taskCompletionSource.Task.ContinueWith(_ =>
            {
                popup.IsOpen = false;
                popup.Child = null;
            }, TaskScheduler.FromCurrentSynchronizationContext());

            // 返回等待的Task
            return _taskCompletionSource.Task;
        }

        private void OnLoginClicked(object sender, RoutedEventArgs e)
        {
            // 用户点击登录,标记任务完成,返回true
            _taskCompletionSource.SetResult(true);
        }

        private void OnCancelClicked(object sender, RoutedEventArgs e)
        {
            // 用户点击取消,标记任务完成,返回false
            _taskCompletionSource.SetResult(false);
        }
    }
}

步骤2:调用ShowAsync方法使用你的UserControl

现在你就能像用ContentDialog一样异步调用了,完全符合你想要的写法:

var loginControl = new LoginUserControl();
bool isLoginConfirmed = await loginControl.ShowAsync();

// 根据用户操作和输入的密码处理逻辑
if (isLoginConfirmed && loginControl.EnteredPassword == "1234")
{
    // 登录成功,执行后续逻辑
    // 比如:Frame.Navigate(typeof(MainPage));
}
else
{
    // 登录失败或用户取消,提示用户
    // 比如:new ContentDialog{Content="密码错误或取消操作", PrimaryButtonText="确定"}.ShowAsync();
}

原理说明

  • TaskCompletionSource是核心:它能帮我们创建一个可手动控制完成状态的Task,当用户点击登录/取消按钮时,调用SetResult完成这个Task,await就会继续执行后续代码。
  • Popup作为容器:它可以把UserControl显示在当前页面之上,完全替代ContentDialog的弹窗效果,而且更灵活可控。

内容的提问来源于stack exchange,提问作者Mg Bhadurudeen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:00:46