c# - WPF MVVM 线程保持运行并在 wpf 窗口中显示进度

标签 c# wpf mvvm

现在我正在 WPF MVVM 中开发后台下载应用程序。当应用程序启动时,下载线程开始工作。我想在每个 WPF 窗口的标签框中显示下载状态,以了解已下载的百分比。

我已经尝试过 BackgroundWorker。我使用HttpClient下载文件,下载过程写在DoWork函数下。

如何从每个 WPF 窗口获取下载进度以显示在标签框中?

欢迎提出任何建议。

最佳研发, 飞镖

最佳答案

您可以使用 BackgroundWorker 或者 Task 来实现这一点。 @razor118 说的是真的;下载服务应该是单例的,或者最好注入(inject)到您的 ViewModel 中,并且在这里需要公开一个事件。

这是(有效但远未完成)示例,使用 TaskEventHandler 来“通知”两个独立的 Window下载进度。

imgur


App.xaml

// where util is xmlns:util="clr-namespace:WpfApplication1.Util"
// Make file downloader a application level resource
<Application.Resources>
    <util:Downloader x:Key="MyDownloader" />
</Application.Resources>

MainWindow.xaml

<Window.DataContext>
    <!-- MainView's data context -->
    <viewModel:MainViewModel />
</Window.DataContext>

<!-- Label to show download progress -->
<Label Content="{Binding Progress}">
    <Label.ContentStringFormat>{0}%</Label.ContentStringFormat>
</Label>

MainWindow.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        // Nothing to do here
        InitializeComponent();
    }
}

MainViewModel.cs

public class MainViewModel : ViewModelBase
{
    private int _progress;

    public MainViewModel()
    {
        // Open new window beside Main
        var otherView = new OtherWindow();
        otherView.Show();

        // Get downloader resource
        var downloader = Application.Current.Resources["MyDownloader"] as Downloader;
        // Update property when ever download progress changes (event)
        downloader.DownloadProgressChanged += (sender, args) => 
            Progress = args.ProgressPercentage;
        // Start downloading a 10Mb file
        downloader.Get("http://mirror.internode.on.net/pub/test/10meg.test");
    }

    public int Progress
    {
        get { return _progress; }
        private set { _progress = value; RaisePropertyChanged();}
    }
}

OtherWindow.xaml(无支持 ViewModel)

<!-- Label to show download progress -->
<Label x:Name="ProgressLabel"></Label>

OtherWindow.cs

public partial class OtherWindow : Window
{
    public OtherWindow()
    {
        InitializeComponent();

        // Get downloader resource
        var downloader = Application.Current.Resources["MyDownloader"] as Downloader;
        // Update label when ever download progress changes (event)
        downloader.DownloadProgressChanged += (sender, args) => 
            ProgressLabel.Content = string.Format("{0}%", args.ProgressPercentage);
    }
}

Downloader.cs

public class Downloader // in WpfApplication.Util namespace
{
    public event EventHandler<DownloadProgressChangedEventArgs> DownloadProgressChanged;

    // Download a file
    public async void Get(string url)
    {
        Uri uri = new Uri(url);
        using (WebClient webClient = new WebClient())
        {
            webClient.DownloadProgressChanged += (sender, args) => OnProgressChanged(args);
            await webClient.DownloadDataTaskAsync(uri);
        }
    }

    // Notify when progress changes
    private void OnProgressChanged(DownloadProgressChangedEventArgs e)
    {
        var handler = DownloadProgressChanged;
        if (handler != null)
            DownloadProgressChanged(this, e);
    }
}

关于c# - WPF MVVM 线程保持运行并在 wpf 窗口中显示进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32680826/

相关文章:

wpf - 数据网格上的 Entity Framework CRUD 操作

c# - 如何在 .net 中将 int 转换为 decimal

WPF ListView - 如何以编程方式添加项目?

c# - DPI 图形屏幕分辨率像素 WinForm PrintPageEventArgs

c# - 使用数据表中的文本填充文本框 - 组合框

c# - IObservableCollection<ViewModel<T>> 包装 ObservableCollection<T>

java - 使用 Google 数据绑定(bind)对 View 宽度进行动画处理

c# - 在 WPF/MVVM 上导航/加载不同的 View

c# - .Any() with Nullables - 当我期望 True 时返回 False

c# - 在方法覆盖中更改 params 修饰符