This is in C#
So I'm trying to create an event for ProgressChanged for multiple webBrowser Controls. These are all dynamically created as well as the progress bar. So i can't call upon it prior. What i'm doing is passing the progress bar through object arrays that are ran. It finally gets to the final method in which i create the browser and need to create the Browser.ProgressChanged event.
Here's the code....
private object[] runTests(string banText, object tabControlName,
object progressBar, int runThisTest, string testName)
{
object[] theReturn = null;
if (stopTests == false)
{
var tabPageBrowser = new TabPage();
var Browser = new WebBrowser();
(tabControlName as TabControl).TabPages.Add(tabPageBrowser);
tabPageBrowser.Name = tabControlName.ToString();
if (banText == "999999999")
{
tabPageBrowser.Text = "History";
}
else
{
tabPageBrowser.Text = testName;
}
tabPageBrowser.Font = new System.Drawing.Font("Trebuchet MS", 8.25F,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
Browser.Dock = DockStyle.Fill;
Browser.Url = new Uri(testStrings(runThisTest, banText));
Browser.Name = tabControlName.ToString();
Browser.ScriptErrorsSuppressed = true;
tabPageBrowser.Controls.Add(Browser);
Browser.ProgressChanged += new WebBrowserProgressChangedEventHandler(Browser_ProgressChanged);
try
{
while (Browser.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
}
catch
{
return null;
}
IntPtr pHandle = GetCurrentProcess();
SetProcessWorkingSetSize(pHandle, -1, -1);
object[] browserObjects = new object[2];
browserObjects[0] = tabPageBrowser;
browserObjects[1] = Browser;
if(browserObjects != null)
{
theReturn = browserObjects;
}
}
return theReturn;
}
Now my question is, how can I add the "progressBar" object when i create the event so i can call upon it when the event has been fired. I'm basically creating a single progress bar for 5+ WebBrowser controls and linking the progress of them together. So for some reason i tried to add the object to the method and it fails out on me. Please assist and Thanks!.
Browser.ProgressChanged += Browser_ProgressChanged;
...
void Browser_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e) {
if (e.MaximumProgress > 0) {
int prog = (int)(100 * e.CurrentProgress / e.MaximumProgress);
progressBar1.Value = prog;
}
}
private ProgressBar progressBar1;
Related
I've been working on a bit of software in c# and it was going nicely but as of yesterday evening I noticed that it was throwing a memory exception error at the point when it loads an image.
I tried to decrease the image size but then realised that 'declaring rats' was being printed repeatedly to the console, where it should only occur once.
Digging a little deeper with some break points I found that it enters the drawing constructor at allRats = new Drawing(HousePicBox, DekuPicBox, BakuPicBox); //THIS HAS BECOME RECURSIVE, WTF
yet it doesn't seem to run the code within the constructor, but jumps back to the start of form1().
I have included all of the code within the files which the Program Counter touches.
//---------------------------------------------------FORM1.CS-------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// This is the code for your desktop app.
// Press Ctrl+F5 (or go to Debug > Start Without Debugging) to run your app.
namespace XMLRats5
{
public partial class Form1 : Form
{
// These are here as they are referred to by various functions for different reasons
string MazakSourceURL = "http://mtconnect.mazakcorp.com:5609"; // Gives us a human friendly reference to the HTML
string NISTSourceURL = "https://smstestbed.nist.gov/vds/current"; // Gives us a human friendly reference to the HTML
public PollTimer statusPoller;
public static Drawing allRats;
ImageRat Deku;
ImageRat Bakugo;
NISTDataSet CurrentNIST;
MazakDataSet CurrentMazak;
public Form1()
{
Console.WriteLine("Declaring Rats..."); // Is being called recursively :( ?????????????
ImageRat.Deku = new Rat(false, 0, 0, true, 0); // Declares Deku
ImageRat.Bakugo = new Rat(false, 800, 0, true, 0); // Declares Bakugo
Console.WriteLine("Initialising");
InitializeComponent(); // Constructs the graphics which make up the 'state 0'
Console.WriteLine("Declaring image");
allRats = new Drawing(HousePicBox, DekuPicBox, BakuPicBox); //THIS HAS BECOME RECURSIVE, WTF
Console.WriteLine("Clearing Image");
allRats.ClearRats();
Console.WriteLine("Displaying House");
HousePicBox.Show();
//allRats.DrawRats(ImageRat.deku.Awake, ImageRat.bakugo.Awake);
Console.WriteLine("Form 1 Initiated, please proceed.");
}
private void NISTDataLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
// This link takes you to the 'current' NIST testbed data feed page
System.Diagnostics.Process.Start(NISTSourceURL);
}
private void MAZAKDataLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
// This link takes you to the raw XML published by Mazaks HCN6800 labelled 5609
System.Diagnostics.Process.Start(MazakSourceURL);
}
public void StatusCheckButton_Click(object sender, EventArgs e) // Here we should check that the machine tools are feeding live data
{
// Clear the rat picture boxes as they 'stick' when already shown
DekuPicBox.Hide();
BakuPicBox.Hide();
string MazakStatus = "Unchecked";
string NISTStatus = "Unchecked";
try
{
CurrentMazak = MTFunctions.PollMazak();
MazakStatus = CurrentMazak.Status;
if (MazakStatus == "AVAILABLE") { ImageRat.Deku.Awake = true; }
}
catch (Exception MazakLookupFailed)
{
Console.WriteLine("Could not retrieve Mazak Data", MazakLookupFailed);
MazakStatus = "Lookup Failed"; // This will later refer to the xml path for running status
}
try
{
CurrentNIST = MTFunctions.PollNIST();
NISTStatus = CurrentNIST.Status;
if (NISTStatus == "AVAILABLE") { ImageRat.Bakugo.Awake = true; }
}
catch (Exception NISTLookupFailed)
{
Console.WriteLine("Could not Retrieve NIST Data: ", NISTLookupFailed);
NISTStatus = "Lookup Failed";
ImageRat.Bakugo.Awake = false;
}
string MessageString = " Mazak : " + MazakStatus + "\n NIST : " + NISTStatus;
if ((ImageRat.Deku.Awake == true) & (ImageRat.Bakugo.Awake == true)) // Both Online
{
HousePicBox.Image = XMLRats5.Properties.Resources.bothsleep; // SLeeping rat shows machine online but not feeding data
} // Empty Box
if ((ImageRat.Deku.Awake == true) & (ImageRat.Bakugo.Awake == false)) // NIST offline
{
HousePicBox.Image = XMLRats5.Properties.Resources.bakusleep;
DekuPicBox.Show(); // Not neccessary but prevents bugs
} // Put Bakug in box, deku out
if ((ImageRat.Deku.Awake == false) & (ImageRat.Bakugo.Awake == true)) // Mazak Offline
{
HousePicBox.Image = XMLRats5.Properties.Resources.dekuSleep;
BakuPicBox.Show(); // Not neccessary but prevents bugs
} // Put deku in box, bakugo out
if ((ImageRat.Deku.Awake == false) & (ImageRat.Bakugo.Awake == false)) // Both Offline
{
HousePicBox.Image = XMLRats5.Properties.Resources.nosleep;
} // Put rats in box
MessageBox.Show(MessageString, "Machine Status"); // We need to pass information gained through XPath to first argument
}
public void WakeRatsButton_Click(object sender, EventArgs e)
{
MessageBox.Show("This 'wakes the rats' (Begins data stream)");
// We need to poll Mazak and NIST here to determine which images to draw.
MazakDataSet checkM = MTFunctions.PollMazak();
NISTDataSet checkN = MTFunctions.PollNIST();
if (checkM.Status == "AVAILABLE")
{
ImageRat.Deku.Awake = true;
DekuPicBox.Show();
}
else { ImageRat.Deku.Awake = false; }
if (checkN.Status == "AVAILABLE")
{
BakuPicBox.Show();
ImageRat.Bakugo.Awake = true;
}
else { ImageRat.Bakugo.Awake = false; }
allRats.DrawRats(ImageRat.Deku.Awake, ImageRat.Bakugo.Awake); // Should move the boys out of the box
// Here the draw function successfully relocates the rats, so why does this not work from the timer?
statusPoller = new PollTimer(2000, true); //Initiate a timer driven function which polls the data sets
// Timer Driven function draws rats
}
public void DebugInstructionsLabel_Click(object sender, EventArgs e)
{ }
public void titleLabel_Click(object sender, EventArgs e) { }
public void SleepRatsButton_Click(object sender, EventArgs e)
{
MessageBox.Show("This 'puts the rats to bed' (Closes data stream)");
try // Stop Polling timer function
{
statusPoller.Stop();
statusPoller.Dispose();
Console.Write("Stream closed successfully");
}
catch { Console.WriteLine("Could not stop polling. Were the rats actually 'awake'?"); }
// Draw rats in house
DekuPicBox.Hide(); // Rat is no longer active
BakuPicBox.Hide(); // Rat is no longer active
HousePicBox.Image = XMLRats5.Properties.Resources.nosleep; // Show empty box
//allRats.Paint();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void HousePicBox_Click(object sender, EventArgs e)
{
}
private void DekuPicBox_Click(object sender, EventArgs e)
{
// Proves that problem with movement is because DekuPicBox needs to be changed, not allRats.dekuPic....
System.Drawing.Point DekuCoord = new System.Drawing.Point(ImageRat.Deku.PosX, ImageRat.Deku.PosY); // Create a 'System Point' for Deku
DekuPicBox.Location = DekuCoord;
Console.WriteLine("~~~~~~~~Deku moved to " + DekuCoord + " ~~~~~~~~");
}
private void BakuPicBox_Click(object sender, EventArgs e)
{
System.Drawing.Point BakuCoord = new System.Drawing.Point(ImageRat.Bakugo.PosX, ImageRat.Bakugo.PosY); // Create a 'System Point' for Deku
BakuPicBox.Location = BakuCoord;
Console.WriteLine("~~~~~~~~Bakugo moved to " + BakuCoord + " ~~~~~~~~");
}
public void Refresh(int boi) // Better bloody relocate those pics boii
{
if (boi == 0)
{
System.Drawing.Point BakuCoord = new System.Drawing.Point(ImageRat.Bakugo.PosX, ImageRat.Bakugo.PosY); // Create a 'System Point' for Deku
DekuPicBox.Location = BakuCoord;
}
else
{
System.Drawing.Point DekuCoord = new System.Drawing.Point(ImageRat.Deku.PosX, ImageRat.Deku.PosY); // Create a 'System Point' for Deku
DekuPicBox.Location = DekuCoord;
}
}
}
}
//----------------------------------------------FORM1.Designer.CS--------------------------------------------------------
namespace XMLRats5
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.MAZAKDataLinkLabel = new System.Windows.Forms.LinkLabel();
this.DebugInstructionsLabel = new System.Windows.Forms.Label();
this.StatusCheckButton = new System.Windows.Forms.Button();
this.TitleLabel = new System.Windows.Forms.Label();
this.WakeRatsButton = new System.Windows.Forms.Button();
this.SleepRatsButton = new System.Windows.Forms.Button();
this.NISTDataLinkLabel = new System.Windows.Forms.LinkLabel();
this.BakuPicBox = new System.Windows.Forms.PictureBox();
this.HousePicBox = new System.Windows.Forms.PictureBox();
this.DekuPicBox = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.BakuPicBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.HousePicBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.DekuPicBox)).BeginInit();
this.SuspendLayout();
//
// MAZAKDataLinkLabel
//
this.MAZAKDataLinkLabel.AutoSize = true;
this.MAZAKDataLinkLabel.Location = new System.Drawing.Point(1287, 985);
this.MAZAKDataLinkLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.MAZAKDataLinkLabel.Name = "MAZAKDataLinkLabel";
this.MAZAKDataLinkLabel.Size = new System.Drawing.Size(179, 25);
this.MAZAKDataLinkLabel.TabIndex = 0;
this.MAZAKDataLinkLabel.TabStop = true;
this.MAZAKDataLinkLabel.Text = "View Mazak Data";
this.MAZAKDataLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.MAZAKDataLinkLabel_LinkClicked);
//
// DebugInstructionsLabel
//
this.DebugInstructionsLabel.AutoSize = true;
this.DebugInstructionsLabel.Location = new System.Drawing.Point(1066, 524);
this.DebugInstructionsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.DebugInstructionsLabel.Name = "DebugInstructionsLabel";
this.DebugInstructionsLabel.Size = new System.Drawing.Size(623, 50);
this.DebugInstructionsLabel.TabIndex = 1;
this.DebugInstructionsLabel.Text = "Press \'Check Machine\' to ensure a device is running, otherwise \n don\'t expect muc" +
"h activity from the rats!";
this.DebugInstructionsLabel.Click += new System.EventHandler(this.DebugInstructionsLabel_Click);
//
// StatusCheckButton
//
this.StatusCheckButton.Location = new System.Drawing.Point(1271, 658);
this.StatusCheckButton.Margin = new System.Windows.Forms.Padding(4);
this.StatusCheckButton.Name = "StatusCheckButton";
this.StatusCheckButton.Size = new System.Drawing.Size(195, 54);
this.StatusCheckButton.TabIndex = 2;
this.StatusCheckButton.Text = "Check Machine Status";
this.StatusCheckButton.UseVisualStyleBackColor = true;
this.StatusCheckButton.Click += new System.EventHandler(this.StatusCheckButton_Click);
//
// TitleLabel
//
this.TitleLabel.AutoSize = true;
this.TitleLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.TitleLabel.Location = new System.Drawing.Point(1255, 382);
this.TitleLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.TitleLabel.Name = "TitleLabel";
this.TitleLabel.Size = new System.Drawing.Size(211, 51);
this.TitleLabel.TabIndex = 3;
this.TitleLabel.Text = "XML Rats";
this.TitleLabel.Click += new System.EventHandler(this.titleLabel_Click);
//
// WakeRatsButton
//
this.WakeRatsButton.Location = new System.Drawing.Point(1271, 775);
this.WakeRatsButton.Margin = new System.Windows.Forms.Padding(4);
this.WakeRatsButton.Name = "WakeRatsButton";
this.WakeRatsButton.Size = new System.Drawing.Size(195, 54);
this.WakeRatsButton.TabIndex = 4;
this.WakeRatsButton.Text = "Wake Rats";
this.WakeRatsButton.UseVisualStyleBackColor = true;
//
// SleepRatsButton
//
this.SleepRatsButton.Location = new System.Drawing.Point(1271, 885);
this.SleepRatsButton.Margin = new System.Windows.Forms.Padding(4);
this.SleepRatsButton.Name = "SleepRatsButton";
this.SleepRatsButton.Size = new System.Drawing.Size(195, 54);
this.SleepRatsButton.TabIndex = 5;
this.SleepRatsButton.Text = "Sleep Rats";
this.SleepRatsButton.UseVisualStyleBackColor = true;
//
// NISTDataLinkLabel
//
this.NISTDataLinkLabel.AutoSize = true;
this.NISTDataLinkLabel.Location = new System.Drawing.Point(1287, 1054);
this.NISTDataLinkLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.NISTDataLinkLabel.Name = "NISTDataLinkLabel";
this.NISTDataLinkLabel.Size = new System.Drawing.Size(162, 25);
this.NISTDataLinkLabel.TabIndex = 6;
this.NISTDataLinkLabel.TabStop = true;
this.NISTDataLinkLabel.Text = "View NIST Data";
//
// BakuPicBox
//
this.BakuPicBox.Image = global::XMLRats5.Properties.Resources.bakuTransSmall;
this.BakuPicBox.Location = new System.Drawing.Point(2092, 1388);
this.BakuPicBox.Name = "BakuPicBox";
this.BakuPicBox.Size = new System.Drawing.Size(632, 424);
this.BakuPicBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.BakuPicBox.TabIndex = 9;
this.BakuPicBox.TabStop = false;
//
// HousePicBox
//
this.HousePicBox.Image = global::XMLRats5.Properties.Resources.nosleep;
this.HousePicBox.Location = new System.Drawing.Point(1057, 1388);
this.HousePicBox.Name = "HousePicBox";
this.HousePicBox.Size = new System.Drawing.Size(632, 424);
this.HousePicBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.HousePicBox.TabIndex = 8;
this.HousePicBox.TabStop = false;
//
// DekuPicBox
//
this.DekuPicBox.Image = global::XMLRats5.Properties.Resources.DekuBackgroundTransparent;
this.DekuPicBox.Location = new System.Drawing.Point(12, 1388);
this.DekuPicBox.Name = "DekuPicBox";
this.DekuPicBox.Size = new System.Drawing.Size(632, 424);
this.DekuPicBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.DekuPicBox.TabIndex = 7;
this.DekuPicBox.TabStop = false;
this.DekuPicBox.Click += new System.EventHandler(this.DekuPicBox_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(2736, 1824);
this.Controls.Add(this.BakuPicBox);
this.Controls.Add(this.HousePicBox);
this.Controls.Add(this.DekuPicBox);
this.Controls.Add(this.NISTDataLinkLabel);
this.Controls.Add(this.SleepRatsButton);
this.Controls.Add(this.WakeRatsButton);
this.Controls.Add(this.TitleLabel);
this.Controls.Add(this.StatusCheckButton);
this.Controls.Add(this.DebugInstructionsLabel);
this.Controls.Add(this.MAZAKDataLinkLabel);
this.Margin = new System.Windows.Forms.Padding(4);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.BakuPicBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.HousePicBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.DekuPicBox)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.LinkLabel MAZAKDataLinkLabel;
private System.Windows.Forms.Label DebugInstructionsLabel;
private System.Windows.Forms.Button StatusCheckButton;
private System.Windows.Forms.Label TitleLabel;
private System.Windows.Forms.Button WakeRatsButton;
private System.Windows.Forms.Button SleepRatsButton;
private System.Windows.Forms.LinkLabel NISTDataLinkLabel;
public System.Windows.Forms.PictureBox DekuPicBox;
public System.Windows.Forms.PictureBox HousePicBox;
public System.Windows.Forms.PictureBox BakuPicBox;
}
}
//-------------------------------------------------------------DRAWING.CS----------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Drawing;
using System.Windows.Forms;
namespace XMLRats5
{
public class Drawing : Form1
{
private PictureBox HouseImage;
private PictureBox DekuImage;
private PictureBox BakuImage;
public Drawing(PictureBox house, PictureBox deku, PictureBox baku)
{
HouseImage = house;
DekuImage = deku;
BakuImage = baku;
} // Code is jumping back to form1 call :S
public void ClearRats()
{
//DekuImage.Image.Dispose();
//BakuImage.Image.Dispose();
//HouseImage.Image.Dispose();
HouseImage.Hide();
DekuImage.Hide();
BakuImage.Hide();
}
public void RePaint()
{
//BakuImage.Paint();
//DekuImage.Paint();
//HouseImage.Paint();
}
public void DrawRats(bool DekuWake, bool BakuWake) // Call this function using active status of 2 machines
{
this.ClearRats();
DekuPicBox.SuspendLayout();
BakuPicBox.SuspendLayout();
HousePicBox.SuspendLayout();
System.Drawing.Point DekuCoord = new System.Drawing.Point(ImageRat.Deku.PosX, ImageRat.Deku.PosY); // Create a 'System Point' for Deku
System.Drawing.Point BakuCoord = new System.Drawing.Point(ImageRat.Bakugo.PosX, ImageRat.Bakugo.PosY); // Create a 'System Point' for Bakugo
Console.WriteLine("Randomly Generated Point Assigned (Deku):" + DekuCoord);
Console.WriteLine("Randomly Generated Point Assigned (Baku):" + BakuCoord);
if (DekuWake == false)
{
DekuImage.Hide();
if (BakuWake == false)
{
BakuPicBox.Hide();
HousePicBox.Image = XMLRats5.Properties.Resources.bothsleep;// set HouseImage to both sleep
}
else
{
BakuPicBox.Location = BakuCoord;
BakuPicBox.Show();
HousePicBox.Image = XMLRats5.Properties.Resources.dekuSleep; //Set HouseImage to DekuSleep
}
}
else //DekuWake == true
{
DekuImage.Show();
if (BakuWake == true)
{
HousePicBox.Image = XMLRats5.Properties.Resources.nosleep;//Set House image to nosleep
DekuPicBox.Location = DekuCoord;
DekuPicBox.Show();
BakuPicBox.Location = BakuCoord;
BakuPicBox.Show();
}
else
{
BakuPicBox.Hide();
HousePicBox.Image = XMLRats5.Properties.Resources.bakusleep;// Set house image to bakusleep
DekuPicBox.Location = DekuCoord;
DekuPicBox.Show();
}
}
HousePicBox.Show(); // Out here as it should always happen
}
}
}
Honestly I'm baffled as to why it keeps jumping back to the start of form1.
What have I broken?
As Drawing is derived from Form1 & you create an instance of Drawing in the Form1 constructor - this is going to cause the Form1 constructor to be invoked again which causes the creation of another instance of Drawing which causes ........... -
Note the base class constructor is called before the code in the derived class constructor - which is why you don't get to the code in the Drawing constructor.
it's my first question I'm asking here, so please be gentle with me ;)
So I've actually got two WinForms in my C# application I'm writing at the moment (I'm quite new to C#).
This window has a button, which saves photos from an usb device you selected before in a list box to another folder.
After clicking on this button my main thread is of course busy with copying, so I decided to create another WinForm which contains my ProgressBar.
Foreach completed copy, I want to increment my ProgressBar accordingly.
So I count the number of copies I have to do and give it the progressbar as maximum. But my problem at the moment is, that I really don't know how to increment the ProgressBar without getting a Thread Unsafe Exception.
Here's my ProgressWindow code:
public partial class ProgressWindow : Form
{
BackgroundWorker updateProgressBarThread = new BackgroundWorker();
private Boolean _isThreadRunning = false;
public Boolean IsThreadRunning
{
get { return _isThreadRunning; }
set { _isThreadRunning = value; }
}
private int _progressbarLength;
public int ProgressbarLength
{
get { return _progressbarLength; }
set { _progressbarLength = value; }
}
private int progress = 1;
public ProgressWindow()
{
Show();
InitializeComponent();
}
private void StartUpdateThread(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
// Reports progress to the ProgressChangedEvent function. (Thread Safe)
}
private void FinishProgressThread(object sender, RunWorkerCompletedEventArgs e)
{
if (!_isThreadRunning)
{
MessageBox.Show("Erfolgreich kopiert");
Close();
}
}
private void ProgressChangedEvent(object sender, ProgressChangedEventArgs e)
{
this.copyProgressbar.Value = e.ProgressPercentage;
this.progressStatus.Text = e.ProgressPercentage.ToString();
}
public void CallUpdateThread()
{
updateProgressBarThread.WorkerReportsProgress = true;
updateProgressBarThread.DoWork += new DoWorkEventHandler(StartUpdateThread);
updateProgressBarThread.ProgressChanged += new ProgressChangedEventHandler(ProgressChangedEvent);
updateProgressBarThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(FinishProgressThread);
updateProgressBarThread.RunWorkerAsync();
}
}
I want to increment my ProgressBar with 1 after each succesful copy.
How do I do this from my main thread?
This is the function which actually handles the copy process
private void SaveFile(System.IO.DirectoryInfo root)
{
try
{
IEnumerable<DirectoryInfo> directoriesNames = root.EnumerateDirectories();
// New instance of thread ProgressWindow.
ProgressWindow progress = new ProgressWindow();
progress.CallUpdateThread();
foreach (DirectoryInfo element in directoriesNames)
{
// Query all subdirectories and count everything with the in the configuration made settings.
if (!element.Attributes.ToString().Contains("System"))
{
// Now we insert the configuration we applied.
String fileExtension = null;
if (Properties.Settings.Default._configPhoto)
{
fileExtension = "*.jpg";
}
if (Properties.Settings.Default._configWordDocument)
{
fileExtension = "*.odt";
}
FileInfo[] jpgList = element.GetFiles(fileExtension, SearchOption.AllDirectories);
// set the size of the progress bar
progress.ProgressbarLength = jpgList.Count();
// Now we go through all our results and save them to our backup folder.
foreach (FileInfo tmp in jpgList)
{
string sourceFilePath = tmp.FullName;
string destFilePath = PATHTOBACKUP + "\\" + tmp.Name;
progress.IsThreadRunning = true;
try
{
System.IO.File.Copy(sourceFilePath, destFilePath, true);
}
catch (IOException ioe)
{
MessageBox.Show(ioe.Message);
}
}
}
}
// progress.IsThreadRunning = false;
}
catch (UnauthorizedAccessException e)
{
MessageBox.Show(e.Message);
}
}
It's pretty obvious that I have to do this after this function
System.IO.File.Copy(sourceFilePath, destFilePath, true);
But how do I report this to my ProgressWindow?
I really hope I explained it well enough, not sure if I'm missing something important.
Thanks in advance guys
Here is a compact example of the key components:
Clicking button starts new thread worker
Progress is done by file lengths, not by number of files
BeginInvoke used to update the progress bar (avoid cross Thread exception)
ProgressBar pb = new ProgressBar() { Minimum = 0, Maximum = 100 };
Button btn = new Button();
btn.Click += delegate {
Thread t = new Thread(() => {
DirectoryInfo dir = new DirectoryInfo("C:\\temp\\");
var files = dir.GetFiles("*.txt");
long totalLength = files.Sum(f => f.Length);
long length = 0;
foreach (var f in files) {
length += f.Length;
int percent = (int) Math.Round(100.0 * length / totalLength);
pb.BeginInvoke((Action) delegate {
pb.Value = percent;
});
File.Copy(f.FullName, "...");
}
});
t.IsBackground = true;
t.Start();
};
How could i save listbox items even if i restart the app in the windows phone app. I want them to be sort of saved somehow, in a file, and then read them on the next start of the app. Please help..
Ok i am updating with a code:
public partial class MainPage : PhoneApplicationPage
{
#region VariableDeclaration
DispatcherTimer timer = new DispatcherTimer();
WebClient client = new WebClient();
WebBrowserTask Facebook = new WebBrowserTask();
WebBrowserTask YouTube = new WebBrowserTask();
WebBrowserTask Odnoklassniki = new WebBrowserTask();
WebBrowserTask Vkontakte = new WebBrowserTask();
List<ItemFormat> Items = new List<ItemFormat>();
DispatcherTimer PopulateIsoFile = new DispatcherTimer();
string SongBuffer;
int c = 1;
string Time;
#endregion
#region AppInit
// Constructor
public MainPage()
{
InitializeComponent();
if (Microsoft.Phone.Net.NetworkInformation.DeviceNetworkInformation.IsNetworkAvailable == false)
{
MessageBox.Show("No internet connection", "Error", MessageBoxButton.OKCancel);
}
else
{
if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing)
{
PauseBtn.Visibility = Visibility.Visible;
PlayBtn.Visibility = Visibility.Collapsed;
}
else
{
BackgroundAudioPlayer.Instance.Track = new AudioTrack(new Uri("http://air-online2.hitfm.md/hitfm.mp3"), "HITFM", "Включи себя", null, null);
PlayBtn.Visibility = Visibility.Visible;
PauseBtn.Visibility = Visibility.Collapsed;
}
BackgroundAudioPlayer.Instance.PlayStateChanged += Instance_PlayStateChanged;
SlideView.Begin();
SlideView.Completed += SlideView_Completed;
SlideView.AutoReverse = true;
}
timer.Interval = TimeSpan.FromSeconds(30);
timer.Tick += timer_Tick;
timer.Start();
Loaded += timer_Tick;
}
#region DownloadTrackInfo
void timer_Tick(object sender, EventArgs e)
{
try
{
client.Encoding = System.Text.Encoding.UTF8;
client.Headers[HttpRequestHeader.IfModifiedSince] = DateTime.Now.ToString();
client.DownloadStringAsync(new Uri("http://air-online2.hitfm.md/status_hitfm.xsl"));
client.DownloadStringCompleted += client_DownloadStringCompleted;
}
catch (System.Net.WebException)
{
}
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try
{
string[] raw = e.Result.Substring(166).Split('-');
if (raw[0].Contains(":"))
{
Artist.Text = raw[0].Replace(":", string.Empty).Substring(0, raw[0].Length - 1);
Title.Text = raw[1].Substring(1);
}
else
{
Artist.Text = raw[0];
Title.Text = raw[1].Substring(1);
}
TitleProgress.Visibility = Visibility.Collapsed;
Title.Foreground = new SolidColorBrush(Colors.White);
Artist.Foreground = new SolidColorBrush(Colors.White);
if (DateTime.Now.Minute < 10)
{
Time = "0" + DateTime.Now.Minute.ToString();
}
else
{
Time = DateTime.Now.Minute.ToString();
}
ItemFormat Item = new ItemFormat(e.Result.Substring(166).Replace(":", string.Empty), c, DateTime.Now.Hour.ToString() + ":" + Time);
if ((!(Item.Song == SongBuffer)) || (Recent.Items.Count == 0))
{
Recent.Items.Add(Item);
SongBuffer = Item.Song;
c += 1;
}
}
catch (System.SystemException)
{
}
}
}
public class ItemFormat
{
public string Song { get; set; }
public int Count { get; set; }
public string Time { get; set; }
public ItemFormat(string Song, int count, string time)
{
this.Song = Song;
this.Count = count;
this.Time = time;
}
}
}
I use this list box for a sort of a playlist for a radio. But i need my items to be saved even when the user clicks back button or is under lock screen. Please help me save my dear items.
There are several ways to store data between "sessions":
Using files in the IsolatedStorage to serialize to/deserialize from.
Using IsolatedStorageSettings for the same purpose, but with smaller amount of data.
Using database, either SQL CE or sqlite
I suggest that you use the first method because it is the easiest one and you will get the least errors with it. Simply serialize the data to the file whenever you need to, either on application closing or when it changes. You then load the data on startup from the file (if it exists) and fill the initial list.
I have start c# a few time ago, so there is somethings that are totally diferent from java, a few time ago I face a problem about a thread changing the UI (add rows to a DataGridView) and I found that I had to call the method Invoke to make that happen. I did and all works fine, but now I'm facing a new problem. So, I have a frame that will display some labels added dynamically and in Java i would like this:
Thread t = new Thread() {
public void run() {
while (true) {
// for each label
for (it = labels.iterator(); it.hasNext();) {
JLabel lb = it.next();
if (lb.getLocation().x + lb.getWidth() < 0) {
if (msgsRemover.contains(lb.getText().toString())) {
it.remove();
MyPanel.this.remove(lb);
msgsRemover.remove(lb.getText().toString());
} else {
// if there is no message to be removed, this will just continue
// going to the end of the queue
MyPanel.this.remove(lb);
MyPanel.this.add(lb);
}
MyPanel.this.repaint();
MyPanel.this.validate();
}
lb.setLocation(lb.getLocation().x - 3, 0);
}
MyPanel.this.repaint();
try {
SwingUtilities.invokeAndWait(running);
sleep(30);
} catch (InterruptedException ex) {
Logger.getLogger(MyPanel.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(MyPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
};
But in C# I have a problem when the thread does:
MyPanel.this.remove(lb);
MyPanel.this.add(lb);
So I did:
if (lb.Location.X + lb.Width < 0) {
if (msgsRemover.Contains(lb.Text.ToString())) {
labels.Remove(label);
this.Invoke(new MethodInvoker(() => { this.Controls.Remove(lb); }));
msgsRemover.Remove(lb.Text.ToString());
} else {
// if there is no message to be removed, this will just continue
// going to the end of the queue
this.Invoke(new MethodInvoker(() => { this.Controls.Remove(lb); }));
this.Invoke(new MethodInvoker(() => { this.Controls.Add(lb); }));
}
this.Invoke(new MethodInvoker(() => { this.Refresh(); }));
But know I'm getting an error called "Can not call Invoke or BeginInvoke on a control until the window handle has been created."
I have searched for solutions but I didn't find out what can I do to solve this.
Thank you in advance for your help!
Edit: start the thread is the last thing I do in the constructor... There is the code:
public MyPanel(Color corLabel, Color back, Font text){
this.color = corLabel;
this.backg = back;
this.textFont = text;
this.Width = 500000;
texto = new LinkedList<string>();
msgs = new LinkedList<MensagemParaEcra>();
labels = new LinkedList<Label>();
var it = labels.GetEnumerator();
var it2 = msgsRemover.GetEnumerator();
this.FlowDirection = FlowDirection.LeftToRight;
this.BackColor = backg;
this.Size = new Size(500000, 30);
this.Refresh();
startThread();
}
You must start the thread after the control has a handle created in order to be able to do Invoke, the easiest way to do that is override the OnHandleCreated method and start your thread there instead.
public MyPanel(Color corLabel, Color back, Font text)
{
this.color = corLabel;
this.backg = back;
this.textFont = text;
this.Width = 500000;
texto = new LinkedList<string>();
msgs = new LinkedList<MensagemParaEcra>();
labels = new LinkedList<Label>();
var it = labels.GetEnumerator();
var it2 = msgsRemover.GetEnumerator();
this.FlowDirection = FlowDirection.LeftToRight;
this.BackColor = backg;
this.Size = new Size(500000, 30);
this.Refresh();
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
startThread();
}
The error you are receiving indicates that the target Window hasn't fully created yet. Probably the constructor hasn't finished. Try to hook up to one of the default events (Load, Show etc.) of the target window and make the invoke calls after these are handled.
Im trying to load a dataGridView which takes some time, so ive come up with an idea of hiding the datagridview and put an image over the top which says Loading... when finished, the image goes away and the datagrid reappears. Ive tried to do this using threading but having no luck.
Can somebody tell me if i am approaching this in the right way?
Label loadingText = new Label();
PictureBox loadingPic = new PictureBox();
private void TelephoneDirectory_Load(object sender, EventArgs e)
{
dataGridView1.Visible = false;
Thread i = new Thread(LoadImage);
i.Start();
Thread t = new Thread(LoadData);
t.Start();
}
void LoadImage()
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(LoadImage));
}
else
{
loadingPic.Image = Properties.Resources.ReportServer;
loadingPic.Location = new Point(0, 0);
loadingPic.Name = "loadingPic";
loadingPic.Dock = DockStyle.Fill;
loadingPic.SizeMode = PictureBoxSizeMode.CenterImage;
loadingText.Text = "Loading, please wait...";
loadingText.Name = "loadingText";
loadingText.TextAlign = ContentAlignment.MiddleCenter;
loadingText.Size = new Size(this.Size.Width, 30);
loadingText.Font = new System.Drawing.Font("Segoe UI", 9);
loadingText.Location = new Point(0, (this.Size.Height / 2 + 10));
this.Controls.AddRange(new Control[] { loadingPic, loadingText });
loadingText.BringToFront();
}
}
private void LoadData()
{
if (dataGridView1.InvokeRequired)
{
dataGridView1.Invoke(new MethodInvoker(this.LoadData));
}
else
{
DirectorySearcher sea = null;
DirectoryEntry dir = null;
DirectoryEntry d = null;
string domainname = System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain().Name;
domainname = domainname.Replace(".", ",DC=");
try
{
dir = new DirectoryEntry();
dir.Path = "LDAP://DC=" + domainname;
sea = new DirectorySearcher(dir);
sea.Filter = "(&(objectClass=user)(extensionAttribute1=1)(telephoneNumber=*))";
sea.PageSize = 2000;
SearchResultCollection res = sea.FindAll();
foreach (SearchResult result in res)
{
//DO ALL MY STUFF
dataGridView1.Rows.Add(row);
}
}
catch { }
LoadDataComplete();
}
}
void LoadDataComplete()
{
PictureBox loadingGraphic = this.Controls["loadingPic"] as PictureBox;
Label LoadingLabel = this.Controls["loadingText"] as Label;
DataGridView dataGrid = this.Controls["dataGridView1"] as DataGridView;
dataGrid.Visible = true;
LoadingLabel.Visible = false;
LoadingLabel.Dispose();
loadingGraphic.Visible = false;
loadingGraphic.Dispose();
dataGridView1.Sort(dataGridView1.Columns[0], ListSortDirection.Ascending);
dataGridView1.ClearSelection();
}
Spawning threads for this might not be the best idea, you could use ThreadPool or BackgroundWorker
Loading image should be fast enough that you could just do it synchronously, so make sure you actually need to do some operation on the other thread before you actually need it.
Ask yourself questions like: what if actually my image will load later then my dataTable? ("but it loads faster every time I checked" is not an valid argument when talking about threads)
At the beginning of your methods you are using .Invoke which basically means "wait for UI thread and invoke my code on it synchronously" which bombards your whole idea.
Try something like this:
Load image synchronously
Use ThreadPool to load your DataTable in it, but without using .Invoke
When it's loaded and you need to interact with UI -> then put your code in .Invoke()
Pseudocode coud look like this:
private void TelephoneDirectory_Load(object sender, EventArgs e)
{
dataGridView1.Visible = false;
LoadImage();
ThreadPool.QueueUserWorkItem(new WaitCallback(o => LoadData()));
}
void LoadData()
{
//...Do loading
//but don't add rows to dataGridView
if (dataGridView1.InvokeRequired)
{
//Invoke only the ui-interaction code
dataGridView1.Invoke(new MethodInvoker(this.LoadDataComplete));
}
}
void LoadDataComplete()
{
foreach (SearchResult result in res)
{
//DO ALL MY STUFF
//If do all my stuff is compute intensive and doesn't require UI,
//put it before Invoke() (like here)
dataGridView1.Rows.Add(row);
}
//Rest of code
}