int i = 0;
private void button1_Click(object sender, EventArgs e)
{
for (int j = 10; j < 1000; j = j + 1)
{
string y = i.ToString();
webBrowser1.Document.GetElementById("lst-ib").SetAttribute("value", y);
i++;
}
}
This is the section of code I'm working with in a windows form application
I want it to input the value and show it going up however it just jumps to the end and puts the last output instead of counting up.
Some people said to use timers but I haven't been able to get them to work.
Any ideas?
You're locking up the UI thread with your loop, so that it doesn't update the control until it's done with its work. You end up only seeing the final value, when the loop is complete and the UI refreshes.
Take a look at using a Timer control instead. You can tell it to raise an event at regular intervals, and it'll allow your UI to be updated correctly.
Add a Timer to your Form and then insert the following code into your constructor to try it out. Currently, it updates your element every 1 ms (in reality, it won't be that fast).
int i = 0;
int j = 10;
timer1.Interval = 1;
timer1.Tick += (s, e) =>
{
string y = i.ToString();
webBrowser1.Document.GetElementById("lst-ib").SetAttribute("value", y);
i++;
j++;
if (j > 1000)
timer1.Stop();
};
timer1.Start();
Related
hope anybody can help me. My problem is the progress bar in C# WinForms. I have the following Code:
(There is a stupid calculate from an uint until a given number from a textbox and i want to show the progress while the calculate method is running)
// The stupid method which calculate
public void ueberlaufUint()
{
try
{
uint ueberlaufZahl = Convert.ToUInt32(textBox1.Text);
do
{
ueberlaufZahl++;
//Console.WriteLine(ueberlaufZahl);
} while (ueberlaufZahl <= 100);
label1.Text = "Endzahl: " + ueberlaufZahl;
}
catch (Exception)
{
MessageBox.Show("Only not negative natural numbers accepted");
}
}
// Buttonclickevent
private async void button1_Click(object sender, EventArgs e)
{
ueberlaufUint();
progressBar1.Maximum = 100;
progressBar1.Step = 1;
var progress = new Progress<int>(v =>
{
// This lambda is executed in context of UI thread,
// so it can safely update form controls
progressBar1.Value = v;
});
// Run operation in another thread
await Task.Run(() => DoWork(progress));
}
// DoWork
public void DoWork(IProgress<int> progress)
{
// This method is executed in the context of
// another thread (different than the main UI thread),
// so use only thread-safe code
for (int j = 0; j < 10000; j++)
{
ueberlaufUint();
// Use progress to notify UI thread that progress has
// changed
if (progress != null)
progress.Report((j + 1) * 100 / 100000);
}
}
The progressbar only counts few steps with no dependency (in my meaning) with the calculate method.
Very great thanks in forward, sorry for my bad english.
Just a typo. You have an extra 0 in the code:
progress.Report((j + 1) * 100 / 100000);
should be
progress.Report((j + 1) * 100 / 10000);
Over the years I've done a significant amount of programming in various forms of BASIC, including Visual Basic. When it comes to C# I'm quite confused. Below is the form load code for a mastermind program I am creating in C#. Everything works, until I try to create my marking routine.
public void Form1_Load(object sender, EventArgs e)
{
//int columns = 14;
Label[,] board = new Label[5,14];
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 14; j++)
{
board[i,j] = new Label();
board[i,j].AutoSize = false;
board[i,j].Size = Dummy.Size;
board[i,j].BorderStyle = BorderStyle.Fixed3D;
board[i,j].BackColor = Color.Beige;
board[i,j].Location = new Point(i * Dummy.Width+2, j * Dummy.Height+2);
board[i,j].Name = "board" + i.ToString() + "," + j.ToString();
board[i,j].Width = Dummy.Width - 4;
board[i,j].Height = Dummy.Height - 4;
board[i,j].TabIndex = 0;
//board[i][j].Text = i.ToString() +" "+ j.ToString();
panel2.Controls.Add(board[i,j]);
board[i,j].Click += new EventHandler(Label1_Click);
}
P2.Click += new EventHandler(P1_Click);
P3.Click += new EventHandler(P1_Click);
P4.Click += new EventHandler(P1_Click);
P5.Click += new EventHandler(P1_Click);
P6.Click += new EventHandler(P1_Click);
P7.Click += new EventHandler(P1_Click);
P8.Click += new EventHandler(P1_Click);
}
int marker = 14;
int each = 5;
Label[,] mark = new Label[each,marker];
// Instantiating all the buttons in the array
for (int i = 0; i < each; i++)
{
for (int j = 0; j < marker; j++)
{
mark[i, j] = new Label();
mark[i, j].AutoSize=false;
mark[i, j].Size = Minnie.Size;
mark[i, j].BorderStyle = Minnie.BorderStyle;
mark[i, j].BackColor = Color.Blue;
mark[i, j].Left = i * (Minnie.Width+2)+3;
mark[i, j].Top = j * Dummy.Height+10;
panel3.Controls.Add(mark[i, j]);
}
}
}
This creates the playing 'holes' for guesses, and smaller marking 'holes' in panels 2 and 3, respectively. The playing part works fine as I have a selection panel that allows the user to choose colors and then 'place' the colors by clicking the board holes array. The various colours are matched by numbers which I append to the .Tag of board elements when they are clicked. The diffculty comes when I try to read the .Tags to assess the guesses for marking. Here is the code that is not working:
public void button1_Click(object sender, EventArgs e)
{
int r;
for (r=0;r<5;r++) {
textBox1.Text = textBox1.Text + board[0,r].Tag;
//board[0, r].BackColor = Color.Azure;
}
}
The board[0, r].BackColor = Color.Azure; was an attempt to isolate where the error derives. It generated the same error, so it seems that the button routine knows that 'board' exists but doesn't acknowledge or is unable to access the subscripted elements. The error generated is:
▶ $exception {"Object reference not set to an instance of an object."} System.NullReferenceException
What do I need to do in order to overcome this difficulty?
Thanks in advance,
Cam
Each variable has a scope: the section of code where that variable is valid. If you define it in a method, then the variable can only be used within that method.
So in this case, if you want to use that variable in multiple methods, you need to declare in a scope that encompasses those methods. In this case, that is your Form1 class - so just inside the declaration of the class, but outside any method.
But you also need to remove the declaration inside Form1_Load too, otherwise you'll end up with two variables with the same name and different scopes. They may have the same name, but they will refer to two different places in memory and not hold the same data. When you use board inside Form1_Load you will refer to the one declared inside that method, and it will be destroyed as soon as the method finishes.
I am creating WPF application. I need to store a temporary value in some variable in one method and I need to get back that value in another method. is there any possible way to store the temporary value in a variable using WPF?
From Comment:
private void Button_Click(object sender, RoutedEventArgs e)
{
count++;
for (int i = 1; i <= count; i++)
{
var tb = new TextBox();
mycanvas.Children.Add(tb);
tb.Name = "txtbox"+i;
tb.Width = 100;
Canvas.SetLeft(tb,50);
Canvas.SetTop(tb, i*20);
}
}
I think you're having a bit of a misunderstanding here ...
WPF (Windows Presentation Foundation), is a technology that came to replace WinForms ...
Storing temp integers would be done exactly like it'll be done in WinForms, Console application or a dll.
You'll save it as a variable that the other method can see (depending on where it is), or send it as a parameter.
If you're talking about MVVM, things get a bit more interesting, but you can still store and send temp variables ...
Having said that, you can also stash away variables in the application settings, and use them (or their default values you can set) however you want. Here's more on this option: MSDN: Application Settings Overview
.
If you want to do something on every i, Jossef Harush is on the money, otherwise (or in addition, you can do something like the following as well:
private int global_variable_name;
private void Button_Click(object sender, RoutedEventArgs e)
{
count++;
for (int i = 1; i <= count; i++)
{
var tb = new TextBox();
mycanvas.Children.Add(tb);
tb.Name = "txtbox"+i;
tb.Width = 100;
Canvas.SetLeft(tb,50);
Canvas.SetTop(tb, i*20);
// You can set global_variable_name here, but it'll be
// silly to set it to `i`, since it's changing
global_variable_name = 8;
}
}
private void SomeOtherMethod() {
// you can use global_variable_name here
var sum = global_variable_name + 3;
}
Welcome you to StackOverflow, i agree with #Noctis answer.
In addition (after reading your comment),
If you would like to pass the current loop's index to a custom method, this is what you should do:
private void Button_Click(object sender, RoutedEventArgs e)
{
int count = 10;
count++;
for (int i = 1; i <= count; i++)
{
var tb = new TextBox();
mycanvas.Children.Add(tb);
tb.Name = "txtbox" + i;
tb.Width = 100;
Canvas.SetLeft(tb, 50);
Canvas.SetTop(tb, i * 20);
// My custom method
MyMethod(i);
}
}
private void MyMethod(int i)
{
// Do something with i
Console.WriteLine(i);
}
I have written a user control using C# Winforms. In the user control, I have three textboxes:
txtStartNumber - input is of type: int.
txtEndNumber - input is of type: int.
txtQuantity - iput is of type: int. (value = txtEndNumber - txtStartNumber)
The progress bar denotes the no. of records added to the database and its total range is set to be equal to txtQuantity.
When one or more records are duplicate, the progress bar is stopped.
My questions are:
How to set the initial value of the progress bar?
How to manage the progress shown by progress bar?
How I save it to the database:
for (long i = from; i < to; i++)
{
for (int j = 0; j < (to - from); j++)
{
arrCardNum[j] = from + j;
string r = arrCardNum[j].ToString();
try
{
sp.SaveCards(r, 2, card_Type_ID, SaveDate, 2);
progressBar1.Value = j;
}
}
}
Try this:
private void StartBackgroundWork() {
if (Application.RenderWithVisualStyles)
progressBar.Style = ProgressBarStyle.Marquee;
else {
progressBar.Style = ProgressBarStyle.Continuous;
progressBar.Maximum = 100;
progressBar.Value = 0;
timer.Enabled = true;
}
backgroundWorker.RunWorkerAsync();
}
private void timer_Tick(object sender, EventArgs e) {
progressBar.Value += 5;
if (progressBar.Value > 120)
progressBar.Value = 0;
}
The Marquee style requires VisualStyles to be enabled, but it continuously scrolls on its own without needing to be updated. I use that for database operations that don't report their progress.
Here is another Progress Bar Tutorial
You can't use loop to do this with progressbar. There is a difference between running code in for, while, do...while loops or in timers. In loops code is immediately done and you can't see this, in timers you can. Even if you try to put in loops if counters, it will not works:
for(int i=a;i<b;++i)
{
if (cnt < 1000000)
{
IncrProgressBar();
cnt++;
}
else
{
cnt = 0;
}
}
If you want to use progressbar to do this then you must put in timer OnTick event code that adds data to database, and in this event increment progressbar value. It's similarly with changing form component's other properties (Text, Size, ...). If you want to see change on component you must use timers.
To change the value use:
private void timer1_Tick(object sender, EventArgs e)
{
progressBar2.Value = progressBar2.Value - 15;
}
In C#
I appreciate your help ahead of time. I'm fairly new to programming, so go easy on me. Right now I have a time-consuming loop which I really need to run outside of the UI thread, because Update() updates a progress bar, which isn't happening till this loop is done. I've looked at some short threading tutorials, and they the updates never render until the big loop is finished.
private void Button_Convert_Click(object sender, RoutedEventArgs e)
{
MachineAngleCalculations.Instance.Arm1Length_Arbitrary = 12;
MachineAngleCalculations.Instance.Arm2Length_Arbitrary = 11;
int resolution = 100000; //points per shape
double xstep, ystep, x, y;
int totalpoints = resolution * ShapeList.Count;
int calculatedpoints = 0;
ProgStat.Update(calculatedpoints, totalpoints, "Calculated", "individual instructions.");
InstructionList.Clear();
foreach (MachineLine item in ShapeList)
{
xstep = (item.End.X - item.Start.X) / (resolution - 1);
ystep = (item.End.Y - item.Start.Y) / (resolution - 1);
for (int i = 0; i < resolution; i++)
{
x = item.Start.X + xstep * i;
y = item.Start.Y + ystep * i;
InstructionList.Add(MachineAngleCalculations.Instance.XYtoMachineInstrution(x, y, 1));
calculatedpoints += 1;
ProgStat.Update(calculatedpoints, totalpoints, "Calculated", "individual instructions.");
}
}
}
So what is the simplest way to execute the foreach loop on a different thread?
Is there a way to do so without putting it in a different function?
You can try:
Aynchronous Programming
Asynchronous Method Invocation (Best tutorial ever!!)
Background Worker
BackgroundWorker Class Sample for Beginners
Simple solution will be using BackgroundWorker Class