This is just a part of the code
A few lines down I'm trying to convert an Int to double. But the fact that the double is an array makes it hard...
I need to include "i" like I did in the previous function, but it wont work, and I get the following error;
No overload for 'webKoordx_OpenReadComplete' matches delegate 'System.Net.OpenReadCompletedEventHandler'
If you know any solution, or is able to see something I've missed, please help me!
private void getKoord(int i)
{
string stringKoX = "http://media.vgy.se/kristoferpk/spots/" + i + "/koordinatx.html";
string stringKoY = "http://media.vgy.se/kristoferpk/spots/" + i + "/koordinaty.html";
var webKoordx = new WebClient();
webKoordx.OpenReadAsync(new Uri(stringKoX));
webKoordx.OpenReadCompleted += new OpenReadCompletedEventHandler(webKoordx_OpenReadComplete);
var webKoordy = new WebClient();
webKoordy.OpenReadAsync(new Uri(stringKoY));
webKoordy.OpenReadCompleted += new OpenReadCompletedEventHandler(webKoordy_OpenReadComplete);
}
void webKoordx_OpenReadComplete(object sender, OpenReadCompletedEventArgs e, int i)//<<-----
{
try
{
using (var reader = new StreamReader(e.Result))
{
koordx = reader.ReadToEnd();
koordx_d[i] = Convert.ToDouble(koordx);
}
}
catch
{
MessageBox.Show("Kan ej ansluta");
MessageBox.Show("Kontrollera din anslutning");
}
}
void webKoordy_OpenReadComplete(object sender, OpenReadCompletedEventArgs e)//<<-----
{
try
{
using (var reader = new StreamReader(e.Result))
{
koordy = reader.ReadToEnd();
koordy_d[i] = Convert.ToDouble(koordy);
}
}
catch
{
MessageBox.Show("Kan ej ansluta");
MessageBox.Show("Kontrollera din anslutning");
}
}
You cannot pass extra information to an event handler like that.
Instead, you can add a lambda expression that handles the event and passes your extra information from its closure:
webKoordx.OpenReadCompleted += (sender, e) => MyMethod(e.Result, i);
Related
I am trying to pass a 2d string array as a parameter to a click event (searchButton_Click) which is generated within a click event so I can perform a search function. However, I get the error No overload for 'searchButton_Click' matches delegate 'RoutedEventHandler'.
I have tried several solutions as seen on stackoverflow and other sources but none has worked.
I'm new to C# programming, any help will be appreciated.
private string[,] LongRunningTask()
{
workSheetName = getWorkSheetName();
var sourceFile = OpenExcelFile(filePath);
var sourceWorkSheet = GetWorkSheet(sourceFile.Item1, sourceFile.Item2, workSheetName); //instantiating the object.
var doc_Max = GetDocRow_Col(sourceWorkSheet.Item1);
var maxRow_Col = GetMaxRow_Col(sourceWorkSheet.Item1, doc_Max.Item1, doc_Max.Item2);
int maxRowCount = maxRow_Col.Item1;
int maxColCount = maxRow_Col.Item2;
WriteLine("Last column with content is Row {0} ", maxRowCount);
WriteLine("Last column with content is Column {0} ", maxColCount);
var getItemsResult = getItems(sourceWorkSheet.Item1, maxRow_Col);
string[,] itemsArr = getItemsResult;
Bindng2DArrayToListview2(listview, itemsArr, maxColCount);
//enableItems();
GarbageCollector(sourceWorkSheet.Item1, sourceWorkSheet.Item2, sourceWorkSheet.Item3, sourceWorkSheet.Item4);
//searchButton.Click += (sender2, e2) => { searchButton_Click(sender2, e2, itemsArr); };
return itemsArr;
}
private async void StartTask()
{
this.progressLabel.Content = "Getting Sheets..";
try
{
await Task.Run(() => LongRunningTask());
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
this.progressLabel.Content = "Done";
}
You could put the result of LongRunningTask into a field on the class (which I assume is the Window itself), then just access that field from searchButton_Click.
For example...
public partial class TheWindow : Window
{
private string[,] LongRunningTask()
{
// Your LongRunningTask implementation.
}
private async Task StartTask()
{
progressLabel.Content = "Getting Sheets...";
try
{
_itemsArr = await Task.Run(() => LongRunningTask());
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
progressLabel.Content = "Done!";
}
private void searchButton_Click(object sender, RoutedEventArgs e)
{
if (_itemsArr == null)
{
// The field is null for some reason. You'll have to decide what to do in this case, but
// naturally you can't use it if it's null.
return;
}
// Do the search using the field _itemsArr.
}
private string[,] _itemsArr = null;
}
I'm creating simple launcher for my other application and I need advise on logical part of the program. Launcher needs to check for connection, then check for file versions (from site), compare it with currently downloaded versions (if any) and if everything is alright, start the program, if not, update (download) files that differs from newest version. The files are:
program.exe, config.cfg and mapFolder. The program.exe and mapFolder must be updated, and config.cfg is only downloaded when there is no such file. Additionaly mapFolder is an folder which contains lots of random files (every new version can have totally different files in mapFolder).
For the file version I thought I would use simple DownloadString from my main site, which may contain something like program:6.0,map:2.3, so newest program ver is 6.0 and mapFolder is 2.3. Then I can use FileVersionInfo.GetVersionInfo to get the version of current program (if any) and include a file "version" into mapFolder to read current version.
The problem is I dont know how to download whole folder using WebClient and what's the best way to do what I want to do. I've tried to download the mapFolder as zip and then automatically unpack it, but the launcher need to be coded in .net 3.0.
Here is my current code, that's just a prototype to get familiar with whole situation, dont base on it.
`
WebClient wc = new WebClient();
string verifySite = "google.com/downloads/version";
string downloadSite = "google.com/downloads/program.exe";
Uri verifyUri, downloadUri = null;
string userVer, currVer = "";
string downloadPath = Directory.GetCurrentDirectory();
string clientName = "program.exe";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(FileDownloaded);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FileDownloadProgress);
chckAutorun.Checked = Properties.Settings.Default.autorun;
checkConnection();
if(!checkVersion())
downloadClient();
else
{
pbDownload.Value = 100;
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
}
private bool checkConnection()
{
verifyUri = new Uri("http://" + verifySite);
downloadUri = new Uri("http://" + downloadSite);
WebRequest req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
verifyUri = new Uri("https://" + verifySite);
downloadUri = new Uri("https://" + downloadUri);
req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
return false;
}
private void downloadClient()
{
try
{
wc.DownloadFileAsync(downloadUri, Path.Combine(downloadPath, clientName));
}
catch { }
}
private bool checkVersion()
{
lblProgress.Text = "checking for updates";
try
{
currVer = FileVersionInfo.GetVersionInfo(Path.Combine(downloadPath, clientName)).FileVersion;
}
catch {
currVer = "";
}
try
{
userVer = wc.DownloadString(verifyUri);
}
catch {
userVer = "";
}
return currVer == userVer && currVer != "";
}
private void FileDownloaded(object sender, AsyncCompletedEventArgs e)
{
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
private void FileDownloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
long received = e.BytesReceived / 1000;
long toReceive = e.TotalBytesToReceive / 1000;
lblProgress.Text = string.Format("{0}KB {1}/ {2}KB", received, Repeat(" ", Math.Abs(-5 + Math.Min(5, received.ToString().Length))*2), toReceive);
pbDownload.Value = e.ProgressPercentage;
}
private void btnPlay_Click(object sender, EventArgs e)
{
btnPlay.Enabled = false;
if(checkVersion())
{
lblProgress.Text = "Starting...";
Process.Start(Path.Combine(downloadPath, clientName));
this.Close();
}
else
{
downloadClient();
}
}
public static string Repeat(string instr, int n)
{
if (string.IsNullOrEmpty(instr))
return instr;
var result = new StringBuilder(instr.Length * n);
return result.Insert(0, instr, n).ToString();
}
private void chckAutorun_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.autorun = chckAutorun.Checked;
Properties.Settings.Default.Save();
}`
I've managed to achieve what I need by enabling autoindex on web server and download string of files in folder ending with .map .
string mapSite = wc.DownloadString(new Uri("http://" + mapsSite));
maps = Regex.Matches(mapSite, "<a href=\"(.*).map\">");
foreach (Match m in maps)
{
string mapName = m.Value.Remove(0, 9).Remove(m.Length - 11);
downloaded = false;
wc.DownloadFileAsync(new Uri("http://" + mapsSite + mapName), Path.Combine(downloadPath, #"mapFolder/" + mapName));
while (!downloaded) { }
}
Whenever I try to convert BinaryReader PeekChar or ReadChar to string it gives me an error
Error 1 'System.IO.BinaryReader.PeekChar()' is a 'method', which is
not valid in the given context
How do I convert it? Here is my code sample:
private void openTextToolStripMenuItem_Click(object sender, EventArgs e)
{
myPath = textBox3.Text;
BinaryReader objBinReader = new BinaryReader(File.Open(myPath, FileMode.Open));
listBox1.Hide();
richTextBox1.Show();
richTextBox1.Text = "";
do
{
try
{
richTextBox1.Text = richTextBox1.Text + objBinReader.ReadChar.toString();
}
catch
{
MessageBox.Show(objBinReader.PeekChar.toString());
}
} while (objBinReader.PeekChar.toString() != "-1");
objBinReader.Close();
}
Thanks in advance!
You are missing the () for the method calls
richTextBox1.Text = richTextBox1.Text + objBinReader.ReadChar().ToString();
and
objBinReader.PeekChar().ToString()
In fact, you're reading the file char after char. Why not do it in one (easy) go?
private void openTextToolStripMenuItem_Click(object sender, EventArgs e)
{
listBox1.Hide();
richTextBox1.Text = File.ReadAllText(textBox3.Text);
richTextBox1.Show();
}
An alternative solution with BinaryReader will be
private void openTextToolStripMenuItem_Click(object sender, EventArgs e)
{
listBox1.Hide();
// when building string in a loop use StringBuilder
StringBuilder sb = new StringBuilder();
// do not close BinaryReader manually, put using instead
using (BinaryReader objBinReader = new BinaryReader(File.OpenRead(textBox3.Text)))
{
// PeekChar() is a method, notice ()
while (objBinReader.PeekChar() != -1)
sb.Append(objBinReader.ReadChar()); // ReadChar() is a method as well
}
richTextBox1.Text = sb.ToString();
richTextBox1.Show();
}
I'm trying to create a simple program to download few files. I've tried some ready-made solutions I found on the web but I can't manage to make it work the way I want it to. I'm using this:
private void startDownload(string toDownload, string saveLocation)
{
Thread thread = new Thread(() =>
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(new Uri(toDownload), saveLocation);
});
thread.Start();
}
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;
labelPercentage.Text = "Downloading " + Convert.ToInt32(percentage) + "% - " + Convert.ToInt32(bytesIn / 1024) + " / " + Convert.ToInt32(totalBytes / 1024) + " kB";
progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString());
});
}
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate
{
textBoxLog.AppendText("OK");
});
}
I'd like to make the program continue (download next file / show the "OK" message / do whatever is in the next line of code) AFTER the download has finished.
In the current form, if I'd put eg.
private void button1_Click(object sender, EventArgs e)
{
startDownload(url, localpath + #"\file.zip");
textBoxLog.AppendText("the cake is a lie");
}
it's showing me this text first and "OK" later.
I'm beginning with c#/.net and I've never learned object-oriented programming before so it's kind of double challenge for me and I can't figure it out by myself. I would be really grateful for relatively easy explanation.
You can have startDownload wait for the asynchronous file download through Application.DoEvents() like this:
private bool downloadComplete = false;
private void startDownload(Uri toDownload, string saveLocation)
{
string outputFile = Path.Combine(saveLocation, Path.GetFileName(toDownload.AbsolutePath));
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(toDownload, outputFile);
while (!downloadComplete)
{
Application.DoEvents();
}
downloadComplete = false;
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
// No changes in this method...
}
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate
{
textBoxLog.AppendText("OK");
downloadComplete = true;
});
}
And the download queue...
private void button1_Click(object sender, EventArgs e)
{
FireDownloadQueue(urls, localpath);
textBoxLog.AppendText("the cake is a lie");
}
private async void FireDownloadQueue(Uri[] toDownload, string saveLocation)
{
foreach (var url in urls)
{
await Task.Run(() => startDownload(url, localpath));
}
}
However, I think you're better off reading about HttpWebRequest and writing your own downloader class with proper checks and events...
Here's a pretty good example by Hemanshu Bhojak (Source) that you can expand upon:
public class Downloader
{
public async Task Download(string url, string saveAs)
{
var httpClient = new HttpClient();
var response = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));
var parallelDownloadSuported = response.Headers.AcceptRanges.Contains("bytes");
var contentLength = response.Content.Headers.ContentLength ?? 0;
if (parallelDownloadSuported)
{
const double numberOfParts = 5.0;
var tasks = new List<Task>();
var partSize = (long)Math.Ceiling(contentLength / numberOfParts);
File.Create(saveAs).Dispose();
for (var i = 0; i < numberOfParts; i++)
{
var start = i*partSize + Math.Min(1, i);
var end = Math.Min((i + 1)*partSize, contentLength);
tasks.Add(
Task.Run(() => DownloadPart(url, saveAs, start, end))
);
}
await Task.WhenAll(tasks);
}
}
private async void DownloadPart(string url, string saveAs, long start, long end)
{
using (var httpClient = new HttpClient())
using (var fileStream = new FileStream(saveAs, FileMode.Open, FileAccess.Write, FileShare.Write))
{
var message = new HttpRequestMessage(HttpMethod.Get, url);
message.Headers.Add("Range", string.Format("bytes={0}-{1}", start, end));
fileStream.Position = start;
await httpClient.SendAsync(message).Result.Content.CopyToAsync(fileStream);
}
}
}
Example usage:
Task.Run(() => new Downloader().Download(downloadString, saveToString)).Wait();
With something along the lines of:
public class Downloader
{
public event EventHandler DownloadProgress;
DownloaderEventArgs downloaderEventArgs;
public void DownloadStarted(DownloaderEventArgs e)
{
EventHandler downloadProgress = DownloadProgress;
if (downloadProgress != null)
downloadProgress(this, e);
}
// ...
}
class DownloaderEventArgs : EventArgs
{
public string Filename { get; private set; }
public int Progress { get; private set; }
public DownloaderEventArgs(int progress, string filename)
{
Progress = progress;
Filename = filename;
}
public DownloaderEventArgs(int progress) : this(progress, String.Empty)
{
Progress = progress;
}
}
startDownload initiates the download on a new thread, so when you invoke startDownload it starts the thread and the rest of the code after that continues immediately because it is on a separate thread. That is why you are seeing "the cake is a lie" before the "OK".
When I open a form which is created at runtime for the second time , I keep getting an error saying "Cannot access a disposed object." "Object name 'Form'" Here is the code of the function. It is called by a buttonclick event. I have looked all over the Net and found people with similar problems, however I have tried those fixes and none of them work. Not sure how to fix this problem. VS highlights the line frmFavorites.Show();
Thank you in advance.
public void frmMyBrowser_ShowFavorites(object sender, EventArgs e)
{
frmFavorites.ShowIcon = false;
frmFavorites.ShowInTaskbar = false;
frmFavorites.Text = "Bookmarks";
frmFavorites.Width = 500;
frmFavorites.Height = 320;
frmFavorites.Controls.Add(lstFavorites);
frmFavorites.Controls.Add(btnRemoveFavorite);
frmFavorites.Controls.Add(btnAddFavorite);
frmFavorites.Controls.Add(txtCurrentUrl);
lstFavorites.Width = 484;
lstFavorites.Height = 245;
btnRemoveFavorite.Location = new Point(397, 255);
btnAddFavorite.Location = new Point(8, 255);
txtCurrentUrl.Location = new Point(110, 255);
txtCurrentUrl.Size = new Size(265, 20);
btnAddFavorite.Text = "Add";
btnRemoveFavorite.Text = "Remove";
txtCurrentUrl.Text = wbBrowser.Url.ToString();
btnAddFavorite.Click += new EventHandler(btnAddFavorite_Click);
btnRemoveFavorite.Click += new EventHandler(btnRemoveFavorite_Click);
frmFavorites.Load += new EventHandler(frmFavorites_Load);
frmFavorites.Show();
frmFavorites.FormClosed += new FormClosedEventHandler(frmFavorites_FormClosed);
StreamReader reader = new System.IO.StreamReader(#Application.StartupPath + "\\favorites.txt");
{
while (!reader.EndOfStream)
{
for (int i = 0; i < 4; i++)
{
string strListItem = reader.ReadLine();
if (!String.IsNullOrEmpty(strListItem))
{
lstFavorites.Items.Add(strListItem);
}
}
}
reader.Close();
}
}
public void btnAddFavorite_Click(object sender, EventArgs e)
{
lstFavorites.Items.Add(wbBrowser.Url.ToString());
}
public void btnRemoveFavorite_Click(object sender, EventArgs e)
{
try
{
lstFavorites.Items.RemoveAt(lstFavorites.SelectedIndices[0]);
}
catch
{
MessageBox.Show("You need to select an item", "Error");
}
}
public void frmFavorites_Load(object sender, EventArgs e)
{
}
public void frmFavorites_FormClosed(object sender, FormClosedEventArgs e)
{
StreamWriter writer = new System.IO.StreamWriter(#Application.StartupPath + "\\favorites.txt");
{
for (int i = 0; i < lstFavorites.Items.Count; i++)
{
writer.WriteLine(lstFavorites.Items[i].ToString());
}
writer.Close();
}
frmFavorites.Close();
}
You cannot reopen a form that has been closed. When a form is closed (1) it is disposed and (2) the underlying operating system Window handle is freed.
I guess you might be able to take the contents of the Form's constructor and put it into a method that you could call to reopen the form, but I really wouldn't recommend doing that even if it does work.
Instead, just create a new instance of the form.
Try this
public void frmMyBrowser_ShowFavorites(object sender, EventArgs e)
{
frmFavorites = new Form();
....
....
}