WPF 数据绑定 ProgressBar
WPF databinding ProgressBar
我正在制作一个 WPF 应用程序,我在其中使用 WebClient
下载文件。我想在 ProgressBar
控制器中显示 ProgressPercentage
。我在 class 中有一个方法,我使用 WebClient
下载文件。我的问题是如何将 ProgressBar
数据绑定到 e.ProgressPercentage
.
Class 中的方法(下载文件):
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"/>
你应该在你的方法中添加一个 IProgress<double> progress
参数,每当你的客户想要更新进度时调用 progress.Report()
。 IProgress
在你的 view/window 端将指向一个方法,你将在其中实现 MyProgressBar.Value = value
或其他任何东西。
使用 IProgress
有效地删除了与将提供更新的目标控件的交互,此外它还负责调用调度程序,因此您不会遇到通常的无效跨线程调用错误。
请参阅此 post 示例:
对于干净的解决方案,您需要一个 ViewModel
class,我们在其中创建了一个 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
& MyWindow.Xaml
:
现在你应该用 DownloadViewModel
class 的实例填充你的 window DataContext
(通过 Xaml 或代码隐藏)。
绑定到 ProgressValue
属性 of DownloadViewModel.cs
class:
<ProgressBar HorizontalAlignment="Left" Height="24" Margin="130,127,0,0" VerticalAlignment="Top" Width="249"
Minimum="0"
Maximum="100"
Value="{Binding Path=ProgressValue}"/>
最后,在您的按钮 OnClick 中写入:
if(this.DataContext!=null)
((DownloadViewModel)this.DataContext).StartDownload("__@Address__","__@Location__");
else
MessageBox.Show("DataContext is Null!");
结果:
我正在制作一个 WPF 应用程序,我在其中使用 WebClient
下载文件。我想在 ProgressBar
控制器中显示 ProgressPercentage
。我在 class 中有一个方法,我使用 WebClient
下载文件。我的问题是如何将 ProgressBar
数据绑定到 e.ProgressPercentage
.
Class 中的方法(下载文件):
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"/>
你应该在你的方法中添加一个 IProgress<double> progress
参数,每当你的客户想要更新进度时调用 progress.Report()
。 IProgress
在你的 view/window 端将指向一个方法,你将在其中实现 MyProgressBar.Value = value
或其他任何东西。
使用 IProgress
有效地删除了与将提供更新的目标控件的交互,此外它还负责调用调度程序,因此您不会遇到通常的无效跨线程调用错误。
请参阅此 post 示例:
对于干净的解决方案,您需要一个 ViewModel
class,我们在其中创建了一个 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
& MyWindow.Xaml
:
现在你应该用 DownloadViewModel
class 的实例填充你的 window DataContext
(通过 Xaml 或代码隐藏)。
绑定到 ProgressValue
属性 of DownloadViewModel.cs
class:
<ProgressBar HorizontalAlignment="Left" Height="24" Margin="130,127,0,0" VerticalAlignment="Top" Width="249"
Minimum="0"
Maximum="100"
Value="{Binding Path=ProgressValue}"/>
最后,在您的按钮 OnClick 中写入:
if(this.DataContext!=null)
((DownloadViewModel)this.DataContext).StartDownload("__@Address__","__@Location__");
else
MessageBox.Show("DataContext is Null!");
结果: