我正在制作一个WPF应用程序,我使用WebClient
来下载文件。我想在ProgressPercentage
控制器中显示ProgressBar
。我在类中使用WebClient
下载文件的方法。我的问题是如何将ProgressBar
数据绑定到e.ProgressPercentage
。
类中的方法(DownloadFile):
public async Task DownloadProtocol(string address, string location)
{
Uri Uri = new Uri(address);
using (WebClient client = new WebClient())
{
//client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
//client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgress);
client.DownloadProgressChanged += (o, e) =>
{
Console.WriteLine(e.BytesReceived + " " + e.ProgressPercentage);
//ProgressBar = e.ProgressPercentage???
};
client.DownloadFileCompleted += (o, e) =>
{
if (e.Cancelled == true)
{
Console.WriteLine("Download has been canceled.");
}
else
{
Console.WriteLine("Download completed!");
}
};
await client.DownloadFileTaskAsync(Uri, location);
}
}
进度:
<ProgressBar HorizontalAlignment="Left" Height="24" Margin="130,127,0,0" VerticalAlignment="Top" Width="249"/>
答案 0 :(得分:4)
要获得干净的解决方案,您需要一个ViewModel
课程,我们会在其中创建StartDownload
方法,您可以通过Command
或button
点击进行调用你的window
。
另一方面,有一个很好的Type
名为IProgress<T>
。它对我们来说是一个 informer ,您可以像下面的示例一样玩它;)
在DownloadViewModel.cs中:
public sealed class DownloadViewModel : INotifyPropertyChanged
{
private readonly IProgress<double> _progress;
private double _progressValue;
public double ProgressValue
{
get
{
return _progressValue;
}
set
{
_progressValue = value;
OnPropertyChanged();
}
}
public DownloadViewModel()
{
_progress = new Progress<double>(ProgressValueChanged);
}
private void ProgressValueChanged(double d)
{
ProgressValue = d;
}
public async void StartDownload(string address, string location)
{
await new MyDlClass().DownloadProtocol(_progress, address, location);
}
//-----------------------------------------------------------------------
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
在MyDlClass中。 CS 强>
public class MyDlClass
{
public async Task DownloadProtocol(IProgress<double> progress, string address, string location)
{
Uri Uri = new Uri(address);
using (WebClient client = new WebClient())
{
//client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
//client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgress);
client.DownloadProgressChanged += (o, e) =>
{
Console.WriteLine(e.BytesReceived + " " + e.ProgressPercentage);
progress.Report(e.ProgressPercentage);
};
client.DownloadFileCompleted += (o, e) =>
{
if (e.Cancelled == true)
{
Console.WriteLine("Download has been canceled.");
}
else
{
Console.WriteLine("Download completed!");
}
};
await client.DownloadFileTaskAsync(Uri, location);
}
}
}
内MyWindow.Xaml.cs
&amp; MyWindow.Xaml
强>
现在,您应该使用DataContext
类的实例(通过Xaml或Code-Behind)填充您的窗口DownloadViewModel
。
绑定到ProgressValue
类的DownloadViewModel.cs
属性:
<ProgressBar HorizontalAlignment="Left" Height="24" Margin="130,127,0,0" VerticalAlignment="Top" Width="249"
Minimum="0"
Maximum="100"
Value="{Binding Path=ProgressValue}"/>
Finnaly,在你的按钮上点击OnClick:
if(this.DataContext!=null)
((DownloadViewModel)this.DataContext).StartDownload("__@Address__","__@Location__");
else
MessageBox.Show("DataContext is Null!");
<强>结果:强>
答案 1 :(得分:0)
您应该在方法中添加IProgress<double> progress
参数,只要您的客户想要更新进度,然后调用progress.Report()
。您的视图/窗口侧的IProgress
将指向您将实施MyProgressBar.Value = value
或其他任何内容的方法。
使用IProgress
有效地删除了与提供更新的目标控件的交互,此外它还负责调用调度程序,因此您不会遇到通常无效的跨线程调用错误。
请参阅此帖子以获取示例: