wpf download file with progress bar

mion shion 241 Reputation points
2023-01-30T19:52:35.0466667+00:00

Hello All thank you for taking the time to read,

so i have upgraded my project from windows forms to wpf because the better ui and you have total control however i have a issue,

the download code is,

 public async Task downloaderpython(string path)
        {

            if(os == "x86")
            {

                if(!Directory.Exists("C:\\Temp"))
                {
                    Directory.CreateDirectory("C:\\Temp");

                    path = @"C:\Temp\" + "python-3.11.0-amd64.exe";
                    filepath = path;
                    filename = "python-3.11.0-amd64.exe";
                    httpdownloader = new HttpDownloader("https://www.python.org/ftp/python/3.11.0/python-3.11.0-amd64.exe", @"C:\Temp\" + Path.GetFileName("https://www.python.org/ftp/python/3.11.0/python-3.11.0-amd64.exe"));
                    httpdownloader.DownloadCompleted += Httpdownloader_DownloadCompleted;
                    httpdownloader.ProgressChanged += Httpdownloader_ProgressChanged;
                    Task.Run(() => httpdownloader.Start());
                }
                else
                {
                    path = @"C:\Temp\" + "python-3.11.0-amd64.exe";
                    filepath = path;
                    filename = "python-3.11.0-amd64.exe";
                    httpdownloader = new HttpDownloader("https://www.python.org/ftp/python/3.11.0/python-3.11.0-amd64.exe", @"C:\Temp\" + Path.GetFileName("https://www.python.org/ftp/python/3.11.0/python-3.11.0-amd64.exe"));
                    httpdownloader.DownloadCompleted += Httpdownloader_DownloadCompleted;
                    httpdownloader.ProgressChanged += Httpdownloader_ProgressChanged;
                    Task.Run(() => httpdownloader.Start());
                }
            }
            else
            {


                if(!Directory.Exists("C:\\Test"))
                {
                    Directory.CreateDirectory("C:\\Test");

                    path = @"C:\Temp\" + "python-3.11.0.exe";
                    filepath = path;
                    filename = "python-3.11.0.exe";
                    httpdownloader = new HttpDownloader("https://www.python.org/ftp/python/3.11.0/python-3.11.0.exe", @"C:\Temp\" + Path.GetFileName("https://www.python.org/ftp/python/3.11.0/python-3.11.0.exe"));
                    httpdownloader.DownloadCompleted += Httpdownloader_DownloadCompleted;
                    httpdownloader.ProgressChanged += Httpdownloader_ProgressChanged;
                    Task.Run(() => httpdownloader.Start());
                }
                else
                {
                    path = @"C:\Temp\" + "python-3.11.0.exe";
                    filepath = path;
                    filename = "python-3.11.0.exe";
                    httpdownloader = new HttpDownloader("https://www.python.org/ftp/python/3.11.0/python-3.11.0.exe", @"C:\Temp\" + Path.GetFileName("https://www.python.org/ftp/python/3.11.0/python-3.11.0.exe"));
                    httpdownloader.DownloadCompleted += Httpdownloader_DownloadCompleted;
                    httpdownloader.ProgressChanged += Httpdownloader_ProgressChanged;
                    Task.Run(() => httpdownloader.Start());
                }


            }

so in win forms i used a addon called Altohttp ( this is not available in .netcore )

but the big issue i have is delegates and how to get text block and and getting the required fields here,

        private void Httpdownloader_ProgressChanged(object sender, AltoHttp.ProgressChangedEventArgs e)
        {
            UpdateProgressBar((int)e.Progress);
            lbl_percent.Text = $"{e.Progress.ToString("0.00")} %";
            lbl_speed.Text = string.Format("{0} MB/s", (e.SpeedInBytes / 1024d / 1024d).ToString("0.00"));
            lbl_downloaded.Text = string.Format("{0} MB/s", (httpdownloader.TotalBytesReceived / 1024d / 1024d).ToString("0.00"));
            lbl_status.Text = "Downloading: " + filename;

        }

but unable to do this due to not being able to use Altohttp

second issue i have

        public static void InvokeIfRequired(Control control, MethodInvoker action)
        {
            if (control.IsDisposed)
            {
                return;
            }
            if (control.InvokeRequired)
            {
                try
                {
                    control.Invoke(action);
                }
                catch (ObjectDisposedException) { }
                catch (InvalidOperationException e)
                {
                    // Intercept only invokation errors (a bit tricky)
                    if (!e.Message.Contains("Invoke"))
                    {
                        throw e;
                    }
                }
            }
            else
            {
                action();
            }
        }

delegates for xmal i have no idea how to work around this,

xaml i have currently its only a muck up as i not sure how to proceed and cant seem to find any good tutorials on this,

<Grid>
        <Grid.Style>
            <Style/>
        </Grid.Style>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="200"/>
            <ColumnDefinition Width="*"/>


        </Grid.ColumnDefinitions>


        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>


        <Border Grid.Row="2" Height="110" Background="#623ed0" CornerRadius="20 20 0 0"  Grid.RowSpan="2" VerticalAlignment="Bottom" Grid.ColumnSpan="3">
            <DockPanel  Grid.Row="2" Grid.RowSpan="2" Margin="0 20">
                <TextBlock Text="Project Kaori Downloader
                           " Background="#623ed0"
                           Foreground="White"
                           FontSize="18"/>
            </DockPanel>

            
            
        </Border>
        <Image  Source="Resources\KaoriDownload.png"  x:Name="elfen"  Width="140" Height="110"  Grid.Row="2" VerticalAlignment="Bottom"
                   Grid.RowSpan="2" Margin="0 0 -1303 0" RenderOptions.BitmapScalingMode="Fant">

        </Image>
        
        

        








    </Grid>
</Window>

Any Help would be much appricated.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,682 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,319 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
768 questions
0 comments No comments
{count} votes

Accepted answer
  1. Hui Liu-MSFT 40,786 Reputation points Microsoft Vendor
    2023-01-31T07:54:59.3466667+00:00

    For problems with using ProgressBar to display the download process in wpf, you could try to refer to the code below.

    Xaml:

      <Window.DataContext>
            <local:ViewModel/>
        </Window.DataContext>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <DataGrid AutoGenerateColumns="False" x:Name="servers"   ItemsSource="{Binding View}" CanUserAddRows="False"  
                      HorizontalAlignment="Center" VerticalAlignment="Top"  Grid.Column="1"  >
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ID" IsReadOnly="True" Binding="{Binding Id}" Width="50"/>
                    <DataGridTextColumn Header="Text" IsReadOnly="True" Binding="{Binding Text}" Width="50"/>
                    <DataGridTemplateColumn Header="Progress"   Width="100">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ProgressBar x:Name="progressbar" Maximum="100" Width="140" Height="20" Value="{Binding Progress}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Header="PValue" IsReadOnly="True" Width="50" Binding="{Binding ProgressValue}"/>
                    <DataGridTemplateColumn Header="Action" Width="50">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate >
                                <Button  Command="{Binding}">
    
                                    <Image Height="50" Width="50" Source="down.jfif"></Image>
                                </Button>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
    

    Codebehind:

     public class ViewModel
    
    {
        CollectionViewSource cvs = new CollectionViewSource();
        public ICollectionView View { get => cvs.View; }
        public ObservableCollection<Clients> MyClients;
        public ViewModel()
        {
    
            cvs.Source = GetData();
        }
        private ObservableCollection<Clients> GetData()
        {
            ObservableCollection<Clients> MyClients = new ObservableCollection<Clients>();
    
            MyClients.Add(new Clients() { Id = 1, Text = "https://sample-videos.com/doc/Sample-doc-file-1000kb.doc" });
            MyClients.Add(new Clients() { Id = 3, Text = "https://freetestdata.com/wp-content/uploads/2021/09/1-MB-DOC.doc" });
    
    
            return MyClients;
        }
    }
    
    public class Clients : ICommand, INotifyPropertyChanged
    {
        public Clients() => disp = Dispatcher.CurrentDispatcher;
    
        private Dispatcher disp;
        public int Id { get; set; }
        public string Text { get; set; }
        public int Status { get; set; }
        public string ProgressValue { get; set; }
    
        WebClient client1 = new WebClient();
        public void Execute(object parameter)
        {
            if (client1.IsBusy) return;
            Progress = 0;
            Uri uri = new Uri(Text);
            String FileName = System.IO.Path.GetFileName(uri.AbsolutePath);
            client1.DownloadFileAsync(uri, @"C:\Users\Administrator\Desktop\" + FileName);
            client1.DownloadProgressChanged += downloadprogress;
            client1.DownloadFileCompleted += Client_DownloadFileCompleted;
        }
        public double Progress { get; set; }
        private void downloadprogress(object sender, DownloadProgressChangedEventArgs e)
        {
            Progress = e.ProgressPercentage;
            double receive = double.Parse(e.BytesReceived.ToString());
            double total = double.Parse(e.TotalBytesToReceive.ToString());
            double percentage = receive / total * 100;
    
          
                ProgressValue = $"{string.Format("{0:0.##}", percentage)}%";
                Status = int.Parse(Math.Truncate(percentage).ToString());
    
            
            OnPropertyChanged(nameof(Progress));
            OnPropertyChanged(nameof(ProgressValue));
            OnPropertyChanged(nameof(Status));
        }
        private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            System.Windows.Forms.MessageBox.Show("Download OK!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        public event EventHandler CanExecuteChanged;
        public bool CanExecute(object parameter) => true;
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
    

    The result:

    23

    -

    If the response is helpful, please click "Accept Answer" and upvote it. Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful