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

C# UWP应用:点击按钮加载图片时显示ProgressRing

UWP中实现图片加载时显示ProgressRing的完整方案

嘿,这个需求在UWP里实现起来挺顺畅的,核心思路就是监听图片的加载状态,在开始加载时激活ProgressRing,加载完成(或失败)后关闭它。我给你分步骤说明,附完整代码示例:

1. 先搞定XAML布局

首先在页面里放置需要的控件:Image(你说的PictureBox在UWP里对应这个)、ProgressRing和切换按钮。把ProgressRing放在Image的正上方,默认不激活:

<Grid>
    <!-- 用于显示图片的控件 -->
    <Image x:Name="DisplayImage" Width="400" Height="300" Stretch="Uniform"/>
    
    <!-- 加载进度环,默认隐藏(IsActive=false) -->
    <ProgressRing 
        x:Name="LoadingRing" 
        Width="50" 
        Height="50" 
        IsActive="False" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Center"
        Foreground="#FF0078D7"/> <!-- 可以自定义进度环颜色 -->
    
    <!-- 下一张按钮 -->
    <Button 
        x:Name="NextButton" 
        Content="下一张" 
        Click="NextButton_Click" 
        HorizontalAlignment="Bottom" 
        Margin="0,0,0,20"/>
</Grid>

2. 后台C#逻辑实现

我们需要维护一个图片路径列表,点击按钮时切换图片,同时通过BitmapImage的ImageOpened和ImageFailed事件来控制进度环:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using System;
using System.Collections.Generic;
using Windows.UI.Popups;

namespace YourAppNamespace
{
    public sealed partial class MainPage : Page
    {
        // 存储所有图片的路径
        private List<string> _imagePaths;
        // 当前显示的图片索引
        private int _currentImageIndex = -1;

        public MainPage()
        {
            this.InitializeComponent();
            // 初始化图片路径——这里假设图片放在项目的Assets文件夹,命名为Image1到Image10
            _imagePaths = new List<string>();
            for (int i = 1; i <= 10; i++)
            {
                _imagePaths.Add($"ms-appx:///Assets/Image{i}.png");
            }
        }

        private void NextButton_Click(object sender, RoutedEventArgs e)
        {
            // 更新索引,循环显示图片
            _currentImageIndex = (_currentImageIndex + 1) % _imagePaths.Count;

            // 先激活进度环,告诉用户正在加载
            LoadingRing.IsActive = true;

            // 创建BitmapImage来加载图片
            var bitmap = new BitmapImage();
            // 绑定加载完成和失败的事件
            bitmap.ImageOpened += OnImageLoaded;
            bitmap.ImageFailed += OnImageLoadFailed;

            // 设置图片源,开始异步加载
            bitmap.UriSource = new Uri(_imagePaths[_currentImageIndex]);
            DisplayImage.Source = bitmap;
        }

        private void OnImageLoaded(object sender, RoutedEventArgs e)
        {
            // 图片加载完成,关闭进度环
            LoadingRing.IsActive = false;
            // 移除事件监听,避免内存泄漏
            CleanupBitmapEvents(sender as BitmapImage);
        }

        private void OnImageLoadFailed(object sender, ExceptionRoutedEventArgs e)
        {
            // 图片加载失败,也要关闭进度环,还可以给用户提示
            LoadingRing.IsActive = false;
            CleanupBitmapEvents(sender as BitmapImage);
            // 弹出错误提示(可选)
            _ = new MessageDialog($"图片加载失败:{e.ErrorMessage}").ShowAsync();
        }

        private void CleanupBitmapEvents(BitmapImage bitmap)
        {
            if (bitmap != null)
            {
                bitmap.ImageOpened -= OnImageLoaded;
                bitmap.ImageFailed -= OnImageLoadFailed;
            }
        }
    }
}

3. 额外优化建议(MVVM架构适配)

如果你的应用是采用MVVM架构的,更推荐用数据绑定来控制ProgressRing,这样代码更解耦:

ViewModel示例(需实现INotifyPropertyChanged)

using System.ComponentModel;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Popups;
using System.Net.Http;
using System.Threading.Tasks;

public class MainViewModel : INotifyPropertyChanged
{
    private List<string> _imagePaths;
    private int _currentIndex = -1;
    private bool _isLoading;
    private BitmapImage _currentImage;

    public bool IsLoading
    {
        get => _isLoading;
        set { _isLoading = value; OnPropertyChanged(nameof(IsLoading)); }
    }

    public BitmapImage CurrentImage
    {
        get => _currentImage;
        set { _currentImage = value; OnPropertyChanged(nameof(CurrentImage)); }
    }

    public MainViewModel()
    {
        _imagePaths = new List<string>();
        for (int i = 1; i <= 10; i++)
        {
            _imagePaths.Add($"ms-appx:///Assets/Image{i}.png");
        }
    }

    public async Task LoadNextImage()
    {
        IsLoading = true;
        try
        {
            _currentIndex = (_currentIndex + 1) % _imagePaths.Count;
            var bitmap = new BitmapImage();
            // 如果是网络图片,可以用SetSourceAsync等待加载完成
            if (_imagePaths[_currentIndex].StartsWith("http"))
            {
                using var client = new HttpClient();
                var stream = await client.GetStreamAsync(_imagePaths[_currentIndex]);
                await bitmap.SetSourceAsync(stream.AsRandomAccessStream());
            }
            else
            {
                bitmap.UriSource = new Uri(_imagePaths[_currentIndex]);
            }
            CurrentImage = bitmap;
        }
        catch (Exception ex)
        {
            _ = new MessageDialog($"加载失败:{ex.Message}").ShowAsync();
        }
        finally
        {
            IsLoading = false;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

对应的XAML绑定(需先在资源中声明ViewModel)

<Page.Resources>
    <local:MainViewModel x:Key="MainViewModel"/>
</Page.Resources>

<Grid DataContext="{StaticResource MainViewModel}">
    <Image Source="{Binding CurrentImage}" Width="400" Height="300" Stretch="Uniform"/>
    <ProgressRing IsActive="{Binding IsLoading}" Width="50" Height="50" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    <Button Content="下一张" Click="async (s,e) => await ((MainViewModel)DataContext).LoadNextImage()" HorizontalAlignment="Bottom" Margin="0,0,0,20"/>
</Grid>

注意事项

  • 如果图片是从网络加载的,记得在Package.appxmanifest里勾选**Internet(Client)**权限,否则会加载失败。
  • 图片路径要确保正确:本地资源用ms-appx:///前缀,本地文件用ms-appdata:///前缀。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:08:20