WPF数据绑定ProgressBar

时间:2015-08-21 18:48:55

标签: c# wpf data-binding progress-bar

我正在制作一个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"/>

2 个答案:

答案 0 :(得分:4)

要获得干净的解决方案,您需要一个ViewModel课程,我们会在其中创建StartDownload方法,您可以通过Commandbutton点击进行调用你的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!");

<强>结果:

enter image description here

答案 1 :(得分:0)

您应该在方法中添加IProgress<double> progress参数,只要您的客户想要更新进度,然后调用progress.Report()。您的视图/窗口侧的IProgress将指向您将实施MyProgressBar.Value = value或其他任何内容的方法。

使用IProgress有效地删除了与提供更新的目标控件的交互,此外它还负责调用调度程序,因此您不会遇到通常无效的跨线程调用错误。

请参阅此帖子以获取示例:

http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx