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

UWP/C# 实现跟随光标进度环的技术咨询

我之前也碰到过这个需求,UWP里确实没有直接把Progress Ring绑定到光标上的现成API,不过有两种可行的方案,我给你详细说说:

方案一:使用覆盖层+Progress Ring(推荐,简单易实现)

这种方法是在等待新窗口启动的过程中,在当前页面上方盖一个半透明的加载层,里面放Progress Ring,既可以提示用户正在加载,还能阻止用户误操作底层控件,实现起来非常直观。

步骤1:在页面XAML中添加加载覆盖层

把这个覆盖层放在页面的根容器最上层(确保能盖住所有内容):

<Grid>
    <!-- 这里是你原有的页面内容 -->
    
    <!-- 加载覆盖层,默认隐藏 -->
    <Grid x:Name="LoadingOverlay" 
          Background="#7F000000"  <!-- 半透明黑色背景 -->
          Visibility="Collapsed" 
          IsHitTestVisible="True">  <!-- 拦截点击事件,防止操作底层控件 -->
        <ProgressRing x:Name="LoadingRing" 
                      IsActive="True" 
                      Width="60" 
                      Height="60" 
                      Foreground="White"/>
    </Grid>
</Grid>

步骤2:在启动新窗口的代码中控制覆盖层显示/隐藏

用try-finally确保不管新窗口启动成功还是失败,覆盖层都会被隐藏:

private async void OpenNewWindowButton_Click(object sender, RoutedEventArgs e)
{
    // 显示加载覆盖层
    LoadingOverlay.Visibility = Visibility.Visible;

    try
    {
        // 启动新窗口的核心逻辑
        var newAppView = CoreApplication.CreateNewView();
        int newViewId = 0;

        await newAppView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            Frame frame = new Frame();
            frame.Navigate(typeof(YourNewWindowPage));
            Window.Current.Content = frame;
            Window.Current.Activate();
            newViewId = ApplicationView.GetForCurrentView().Id;
        });

        // 切换到新窗口
        bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
    }
    finally
    {
        // 无论结果如何,隐藏加载覆盖层
        LoadingOverlay.Visibility = Visibility.Collapsed;
    }
}
方案二:自定义进度环光标(进阶,真正替换系统光标)

如果你确实需要把光标本身换成进度环样式,就得用自定义光标。不过这个方法相对繁琐,需要准备动画光标文件:

步骤1:生成动画光标文件

UWP支持.ani格式的动画光标,你需要先把Progress Ring的动画帧导出成图片序列,再用工具(比如AniCursor)转换成.ani文件,然后把这个文件放到你的应用Assets文件夹里。

步骤2:在Package.appxmanifest中注册自定义光标

添加如下扩展声明,把光标文件和ID绑定:

<Package ...>
  <Applications>
    <Application ...>
      <!-- 原有内容 -->
      <Extensions>
        <uap:Extension Category="windows.customCursor">
          <uap:CustomCursor>
            <uap:Cursor Id="1" Path="Assets/ProgressRing.ani"/>
          </uap:CustomCursor>
        </uap:Extension>
      </Extensions>
    </Application>
  </Applications>
</Package>

步骤3:在代码中切换光标

在启动新窗口前后切换光标样式:

private async void OpenNewWindowButton_Click(object sender, RoutedEventArgs e)
{
    // 保存原有光标,方便后续恢复
    var originalCursor = Window.Current.CoreWindow.PointerCursor;

    // 设置自定义进度环光标
    var loadingCursor = new CoreCursor(CoreCursorType.Custom, 1);
    Window.Current.CoreWindow.PointerCursor = loadingCursor;

    try
    {
        // 启动新窗口的逻辑(和方案一一致)
        var newAppView = CoreApplication.CreateNewView();
        int newViewId = 0;

        await newAppView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            Frame frame = new Frame();
            frame.Navigate(typeof(YourNewWindowPage));
            Window.Current.Content = frame;
            Window.Current.Activate();
            newViewId = ApplicationView.GetForCurrentView().Id;
        });

        await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
    }
    finally
    {
        // 恢复原有光标
        Window.Current.CoreWindow.PointerCursor = originalCursor;
    }
}

方案对比

  • 方案一实现简单,用户体验清晰,还能防止误操作,适合大多数场景;
  • 方案二更贴近"替换光标"的需求,但需要额外处理光标文件,而且部分UWP控件可能会自行覆盖光标样式,导致效果不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:19:15