Loc*_* Le 2 c# data-binding wpf progress-bar
我正在制作WebClient用于下载文件的WPF应用程序。我想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);
}
}
Run Code Online (Sandbox Code Playgroud)
进度条:
<ProgressBar HorizontalAlignment="Left" Height="24" Margin="130,127,0,0" VerticalAlignment="Top" Width="249"/>
Run Code Online (Sandbox Code Playgroud)
对于一个干净的解决方案,您需要一个ViewModel类,我们在其中创建一个StartDownload方法,您可以通过单击Command或button单击来调用它window。
另一方面,有一个好Type名字IProgress<T>。它可以作为一个线人给我们,你可以用它类似于下面的示例播放;)
在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));
}
}
Run Code Online (Sandbox Code Playgroud)
在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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
内部MyWindow.Xaml.cs和MyWindow.Xaml:
现在,您应该DataContext使用DownloadViewModel类的实例(通过Xaml或Code-Behind)填充窗口。
绑定到类的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}"/>
Run Code Online (Sandbox Code Playgroud)
最后,在您的按钮OnClick中输入:
if(this.DataContext!=null)
((DownloadViewModel)this.DataContext).StartDownload("__@Address__","__@Location__");
else
MessageBox.Show("DataContext is Null!");
Run Code Online (Sandbox Code Playgroud)
结果: