My app for Windows Phone has a string downloaded from server. I'm trying displaying a textBlock while the download is in execution. However, my code doesn't works.
The textBlock is not displayed. Why? Is there another way for this?
WebClient webClient1 = new WebClient();
webClient1.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
webClient1.DownloadStringCompleted += webClient_DownloadStringCompleted1;
webClient1.DownloadStringAsync(new Uri(string.Format(url + insCodComanda.Text + "&random=" + ran.Next().ToString(), UriKind.RelativeOrAbsolute)));
public void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e)
{
testete.Visibility = Visibility.Visible;
}
void webClient_DownloadStringCompleted1(object sender, DownloadStringCompletedEventArgs e)
{
testete.Visibility = Visibility.Collapsed;
}
If you want to manipulate UI element like that you need to use Dispatcher
this.Dispatcher.BeginInvoke(new Action(() => testete.Visibility = Visibility.Visible));
Related
I'm having an issue getting a progressbar to show download progress. The files are downloading without issue, but something is causing my progressbar to not update and I can't figure out why.
I've tried setting the progressBar value manually in the download and wc_DownloadProgressChanged method, but the only place it actually changes is the Form1_Load method.
using System;
using System.Windows.Forms;
using System.Threading;
namespace Launch
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Downloader downloader = new Downloader();
ThreadStart job = new ThreadStart(downloader.download);
Thread thread = new Thread(job);
thread.Start();
}
private void ProgressBar_Click(object sender, EventArgs e)
{
}
public void SetProgress(int val)
{
progressBar.Value = val;
}
public void SetVisible(bool val)
{
progressBar.Visible = val;
}
}
}
using System;
using System.Data;
using System.Net;
using Newtonsoft.Json;
namespace Launch
{
class Downloader
{
public void download()
{
WebClient client = new WebClient();
string url = "https://someurl.com/manifest.json";
string json = client.DownloadString(url);
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json);
DataTable dataTable = dataSet.Tables["Required"];
foreach (DataRow row in dataTable.Rows)
{
string remoteUri = row["url"].ToString();
string fileName = row["name"].ToString();
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadFile(remoteUri, fileName);
Console.WriteLine("Did something with " + remoteUri);
}
}
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
var form = new Form1();
form.SetProgress(e.ProgressPercentage);
}
}
}
Would anyone be able to shed some light on what I'm doing wrong here?
EDIT:
I was able to get this working for the most part using DownloadFileAsync, but the progress bar was bouncing back and forth, I'm assuming because it's trying to calculate the progress for each individual file as bytes are received, so I'd like to get this working with DownloadFile.
The issue I'm now having with DownloadFile is that I have it running as a task but it's skipping all of the files (not downloading any of them, just prints them all out to console super fast).
Here's the code I'm using currently:
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
string url = "https://someurl.com/manifest.json";
string json = client.DownloadString(url);
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json);
DataTable dataTable = dataSet.Tables["Required"];
foreach (DataRow row in dataTable.Rows)
{
string remoteUri = row["url"].ToString();
string fileName = row["name"].ToString();
Task.Run(() => {
client.DownloadFile(remoteUri, fileName);
});
Console.WriteLine("Did something with " + remoteUri);
}
}
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate {
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
label1.Text = "Downloaded ";
label2.Text = e.BytesReceived.ToString();
label3.Text = e.TotalBytesToReceive.ToString();
progressBar.Value = int.Parse(Math.Truncate(percentage).ToString());
});
}
Any ideas?
Use this code below :
private void Form1_Load(object sender, EventArgs e)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadStringCompleted += client_DownloadStringCompleted;
Uri url = new Uri("url");
client.DownloadStringAsync(url);
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
SetVisible(false);
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
SetProgress(e.ProgressPercentage);
}
public void SetProgress(int val)
{
progressBar.Value = val;
}
public void SetVisible(bool val)
{
progressBar.Visible = val;
}
This likely should belong to https://codereview.stackexchange.com/
First of all, do not add a handler in a loop
client.DownloadProgressChanged += client_DownloadProgressChanged;
First time it will be fine, on 2nd item it will be called 2x times, on 3rd time it will be called 3 times, etc. You want to set handler once. Move it just after line:
WebClient client = new WebClient();
Second of all, each time a progress update is fired you are creating a new instance of the form. Create a private variable or property once.
private Form1 form = new Form1();
edit:
In case of UI, usually you can modify it only in the dispatcher thread that created it or use marshaling. I would just remove it as our already downloading the string async.
Also, I would not use e.ProgressPercentage, but something like:
Math.Truncate(e.BytesReceived / (double)e.TotalBytesToReceive * 100)
I am currently making a podcast client to download episodes. I have got a listView filled with the episodes for a feed and then when you double click on one it places it into a separate 'downloads' lisview which has a 'name' and a 'progress' column.
The problem I am having is trying to individually update each progress while downloading asynchronously. As I am not sure of how to keep track of the progress for each ListViewItem and how to reference it in the downloadProgressChanged function.
private void lvPodDownloads_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (lvPodEpisodes.SelectedItems.Count == 1) // Check if an item is selected just to be safe
{
ListViewItem item = (ListViewItem)lvPodEpisodes.SelectedItem;
string[] epInfo = (string[])item.Tag;
txtTitle.Text = epInfo[0];
txtDesc.Text = epInfo[1];
try
{
imgFeedImage.Source = new BitmapImage(new Uri((Environment.CurrentDirectory + "\\..\\..\\feedImages\\" + epInfo[3])));
}
catch (Exception) // If it fails to set the image (Eg. It's non-existent) It will leave it blank
{
imgFeedImage.Source = null;
}
}
}
private void lvPodEpisodes_MouseDoubleClick(object sender, MouseButtonEventArgs e) // Downloading the episode in here
{
if (e.ChangedButton == MouseButton.Left) // Left button was double clicked
{
ListViewItem selected = (ListViewItem)lvPodEpisodes.SelectedItem;
string[] epInfo = (string[])selected.Tag;
Uri downloadUrl = new Uri(epInfo[2]);
List<Episode> downloading = new List<Episode>();
downloading.Add(new Episode() { Title = epInfo[0], Progress = "0%" });
lvPodDownloads.Items.Add((new Episode() { Title = epInfo[0], Progress = "0%" }));
using (WebClient client = new WebClient())
{
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
}
}
}
static int intDownloadProgress = new int();
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
intDownloadProgress = e.ProgressPercentage;
}
private void Completed(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("Download completed!");
}
This is a code sample of the downloading section of the program.
Here is an image of what I have so far:
https://s33.postimg.cc/gthzioxlr/image.png
You should add an extra argument to your ProgressChanged method.
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e, Episode curEpisode)
{
curEpisode.Progress = $"{e.ProgressPercentage} %";
}
And to modify the handler setting like that:
List<Episode> downloading = new List<Episode>();
var newEpisode = new Episode() { Title = epInfo[0], Progress = "0%" };
downloading.Add(newEpisode);
lvPodDownloads.Items.Add(newEpisode);
using (WebClient client = new WebClient())
{
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler((sender, e) => ProgressChanged(sender, e, newEpisode));
}
The static property intDownloadProgress is then useless.
You should also think about using an observable collection for the episode list and using it for the binding via the XAML code.
I am using CefSharp to create a browser. It is working, I can navigate to various websites by using new tab. But when I click on previous tabs, all the tab shows same URL in the address bar and all of them has exactly same title. Here is my code:
private void FormBrowser_Load(object sender, EventArgs e)
{
CefSettings settings = new CefSettings();
Cef.Initialize(settings);
ChromiumWebBrowser browser = new ChromiumWebBrowser(toolStripTextBoxAddress.Text);
browser.Parent = tabControl.SelectedTab;
browser.Dock = DockStyle.Fill;
browser.AddressChanged += Browser_AddressChanged;
browser.TitleChanged += Browser_TitleChanged;
}
// new tab function
public void addNewTab()
{
TabPage tpage = new TabPage();
tpage.Text = "New Tab";
tabControl.Controls.Add(tpage);
tabControl.SelectTab(tabControl.TabCount - 1);
toolStripTextBoxAddress.Text = "";
ChromiumWebBrowser browser = new ChromiumWebBrowser(toolStripTextBoxAddress.Text);
browser.Parent = tpage;
browser.Dock = DockStyle.Fill;
browser.AddressChanged += Browser_AddressChanged;
browser.TitleChanged += Browser_TitleChanged;
}
private void Browser_TitleChanged(object sender, TitleChangedEventArgs e)
{
this.Invoke(new MethodInvoker(() =>
{
tabControl.SelectedTab.Text = e.Title;
}));
}
private void Browser_AddressChanged(object sender, AddressChangedEventArgs e)
{
this.Invoke(new MethodInvoker(() =>
{
toolStripTextBoxAddress.Text = e.Address;
}));
}
// navigate method
private void toolStripTextBoxAddress_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (!string.IsNullOrEmpty(toolStripTextBoxAddress.Text))
{
if (!toolStripTextBoxAddress.Text.Contains("."))
{
getCurrentBrowser().Load("http://www.google.com/search?q=" + toolStripTextBoxAddress.Text);
}
else
{
getCurrentBrowser().Load(toolStripTextBoxAddress.Text);
}
}
}
}
// get current browser
private ChromiumWebBrowser getCurrentBrowser()
{
return (ChromiumWebBrowser)tabControl.SelectedTab.Controls[0];
}
// new tab button
private void toolStripButtonNewTab_Click(object sender, EventArgs e)
{
addNewTab();
}
Here is what I have tried:
private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
{
ChromiumWebBrowser currentBrowser = getCurrentBrowser();
toolStripTextBoxAddress.Text = currentBrowser.Address;
}
When i try to open a new tab it is giving me an error in this line return (ChromiumWebBrowser)tabControl.SelectedTab.Controls[0];
How can I solve this problem? Thanks in advance.
I wrote my multi-tab cefsharp code in a very similar fashion to yours, and encountered the same error.
It was cause by the default number of tab pages. (When you drag tabcontrol to your form, it by default comes with 2 tabpages to start with). From the property panel, I removed those two tabpages, so that the browser starts wit zero tabpage. Any tabpage is only added when you start browsing, by inputting url or clicking favorites.
If you do not set the initial number of tabpages to zero, those two "empty" tabpages have no browser attached to them. Therefore the getcurrentbrowser() function fails to find any browser on those empty tabpages and errors occur.
I know there have been a lot of questions here but I have went through a ton of them and have had little luck. I'm new to events and background workers and I just don't know the best way to implement this.
I have a a basic Windows form in C#. It contains a progress bar. I am calling a class that is to download a file. I want the progress bar to update based on that download. I have it working fine if everything is all in the same class, but I can't get it to work in this situation. What is the best way to handle this and how might I go about it? Currently I'm doing this:
WebClient downloader = new WebClient();
downloader.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
downloader.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
And then for progress changed I do this:
public void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
pbDownload.Value = e.ProgressPercentage;
}
But when I put all of this except for the progress bar in a separate class, it gets all messed up. Ideas? Thanks!
I have this witch is about the same as what you are trying to do and works fine
FStatus ... form reference
FrmStatus FStatus = null;
public void ProgressInit(String caption, string opis, int Max)
{
FStatus = new SZOKZZ.FrmStatus();
FStatus.InitProc(Max);
FStatus.SetCaption(caption, opis);
FStatus.Show();
}
public void DLProgress(string curl, string cdl)
{
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DLDone);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DLSetProc);
webClient.DownloadFileAsync(new Uri(curl), cdl);
}
private void DLSetProc(object sender, DownloadProgressChangedEventArgs e)
{
this._FileProcentDownloaded = e.ProgressPercentage;
FStatus.SetProcDL(this._FileProcentDownloaded);
}
private void DLDone(object sender, AsyncCompletedEventArgs e)
{
_DlError = e.Error;
FStatus.Dispose();
FStatus = null;
}
You should call Application.DoEvents(); to force your form to update controls based on their new values :
public void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
pbDownload.Value = e.ProgressPercentage;
Application.DoEvents();
}
Regards
I have the following piece of code that works great in all but one instance.
private void tbxLastName_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
{
GetRemainingChars(sender);
}
public void GetRemainingChars(object sender)
{
var control = sender as TextEdit;
var maxChars = control.Properties.MaxLength;
tipCharacterCounter.Show(control.Text.Length + "/" + maxChars, this, control.Location.X, control.Location.Y - control.Height);
}
I just repeat this process from any textbox. Unfortunately, I have one control that is more complicated and I cannot get this to work. The Event portion looks like this -->
private void memDirectionsToAddress_Popup(object sender, EventArgs e)
{
MemoExPopupForm popupForm = (sender as DevExpress.Utils.Win.IPopupControl).PopupWindow as MemoExPopupForm;
MemoEdit meDirections = popupForm.Controls[2] as MemoEdit;
meDirections.EditValueChanging += new DevExpress.XtraEditors.Controls.ChangingEventHandler(meDirections_EditValueChanging);
}
void meDirections_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
{
GetRemainingChars(sender);
}
What I don't understand is if I replace the tipCharacterCounter portion with, say updating a label, it works fine. It's like the ToolTip is hidden or something but I have tried feeding Show() different points to no avail.
Ideas?
Which version of DXPerience are you using? I've tried the following code using DXperience 10.1.5 and it works fine here:
private void memoExEdit1_Popup(object sender, EventArgs e) {
MemoExPopupForm popupForm = (sender as DevExpress.Utils.Win.IPopupControl).PopupWindow as MemoExPopupForm;
MemoEdit meDirections = popupForm.Controls[2] as MemoEdit;
meDirections.EditValueChanging += new DevExpress.XtraEditors.Controls.ChangingEventHandler(meDirections_EditValueChanging);
}
void meDirections_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e) {
GetRemainingChars(sender);
}
public void GetRemainingChars(object sender) {
TextEdit control = sender as TextEdit;
int maxChars = control.Properties.MaxLength;
tipCharacterCounter.ShowHint(control.Text.Length + "/" + maxChars, control, ToolTipLocation.RightBottom);
}