Calculated Progress percentage not updating - c#

I'm trying to show the percent value of progression With a background worker in a Label .Im Adding Aprox. 25 K rows to a DataTable. It work fine when I set Label.Text to e.ProgressPercentage only . But when I calculate the % value, it remains same.Only after completion of the worker The label updates to 100%
progressCount = report.Rows.Count;
foreach (DataRow r in report.Rows)
{
rp.pName = r[1].ToString();
rp.batch = r[2].ToString();
rp.expr = r[3].ToString();
rp.stock = r[5].ToString();
rp.rate = r[6].ToString();
backgroundWorker2.ReportProgress(i, rp);
System.Threading.Thread.Sleep(2);
if(backgroundWorker2.CancellationPending)
{
e.Cancel = true;
backgroundWorker2.ReportProgress(0);
}
i++;
}
private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
metroProgressBar1.Minimum = 0;
metroProgressBar1.Maximum = progressCount;
stock st = new stock();
reportClass rp = (reportClass)e.UserState;
if(!backgroundWorker2.CancellationPending)
{
st.stockReport.Rows.Add(rp.pName, rp.batch, rp.expr, rp.stock, rp.rate);
metroProgressBar1.Value = e.ProgressPercentage;
int percn = (e.ProgressPercentage / progressCount) * 100;
metroLabel4.Text =percn.ToString();
}
}

You're most likely dividing an integer by an integer, which results in zero. Cast your values to double first, do the calculation, then cast the result back to an int.
Change:
int percn = (e.ProgressPercentage / progressCount) * 100;
To:
int percn = (int)(((double)e.ProgressPercentage / (double)progressCount) * 100);

Related

How to convert Listview dates to local time zone?

I have 3 columns in the ListView. From,Subject,Date
I'm using the OpenPop library.
private int numberofallmessages = 0;
private int countMsg = 0;
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
OpenPop.Pop3.Pop3Client PopClient = new OpenPop.Pop3.Pop3Client();
PopClient.Connect("mail", 110, false);
PopClient.Authenticate("me", "me",
OpenPop.Pop3.AuthenticationMethod.UsernameAndPassword);
List<string> uids = PopClient.GetMessageUids();
int messageCount = PopClient.GetMessageCount() -1;
numberofallmessages = messageCount;
allMessages = new List<OpenPop.Mime.Message>(messageCount);
for (int i = messageCount; i > 0; i--)//for (int i = messageCount - 1; i > -1; i--)
{
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
return;
}
string currentUidOnServer = uids[i];
if (!seenUids.Contains(currentUidOnServer))
{
if (i > 0)
allMessages.Add(PopClient.GetMessage(i));
SaveFullMessage(PopClient.GetMessage(i), i);
w = new StreamWriter(emailsIDSFile, true);
w.WriteLine(currentUidOnServer);
w.Close();
int nProgress = (messageCount - i + 1) * 100 / messageCount;
backgroundWorker1.ReportProgress(nProgress, PopClient.GetMessageCount().ToString() + "/" + i);
}
}
PopClient.Disconnect();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pbt.Value = e.ProgressPercentage;
pbt.Text = e.ProgressPercentage.ToString() + "%";
pbt.Invalidate();
label8.Text = e.UserState.ToString();
label8.Visible = true;
lvnf.Items.Add(new ListViewItem(new string[]
{
allMessages[countMsg].Headers.From.ToString(), //From Column
allMessages[countMsg].Headers.Subject, //Subject Column
allMessages[countMsg].Headers.DateSent.ToString() //Date Column
}));
countMsg += 1;
}
The problem is in the progresschanged event i think. Where i add the items to each column.
When it's adding the emails to the ListView i see it like this:
The problem is on the date column the date is fine but the time in not my time. Not sure of what place the time is but in my place it's now 1:52 AM
How can i get/set the time of my place ?
I couldn't find in the line:
allMessages[countMsg].Headers.DateSent.ToString()
How to change it to my time.
Try this:
allMessages[countMsg].Headers.DateSent.ToLocalTime().ToString();
You want to utilize the DateTime.ToLocalTime() method. It does the heavy lifting for you.
Hope this helps
Edit: Removed incorrect version as the documentation for OpenPop.Net states that the MessageHeader.DateSent property is in fact a DateTime object.

Why is my List total not computing correctly? C#

I am supposed to get values entered into a text box, then display the total of the entered values, the average of the values, and the count of how many values have been entered.
So far I have coded:
List<int> intScoreList = new List<int>(20);
decimal decScoreAverage = 0m;
decimal decScoreTotal = 0m;
private void btnAdd_Click(object sender, EventArgs e)
{
int intScore = Convert.ToInt32(txtScore.Text);
int intScoreCount = 0;
intScoreList.Add(intScore);
for (int i = 0; i < intScoreList.Count; i++)
{
intScoreList[0] = intScore;
decScoreTotal += intScoreList[i];
intScoreCount++; //correct
decScoreAverage = decScoreTotal / intScoreCount; //correct
}
When I enter test values of 30 then 40, the total gives me 110 (30 + 40 * 2) rather than 70 (30 + 40). Where am I going wrong?
Use Linq. On the add button click event simply add the parsed value. Then display the Avg, and Count.
List<decimal> scoreList = new List<decimal>();
private void btnAdd_Click(object sender, EventArgs e)
{
decimalnum;
if (decimal.TryParse(txtScore.Text, out num))
{
scoreList.Add(num);
}
// Assign to count label Text property = scoreList.Count;
// Assign to average label Text property = scoreList.Average();
}
Now imagine the ability to reset all the user's input:
private void btnReset_Click(object sender, EventArgs e)
{
scoreList.Clear();
}
Utilizing the list instance you can easily add number's as entered and correctly parsed from the user. The Average Linq extension method will do all the math for you, no need to do it yourself.
To the commenters' (justified) point below, here's some more explanation.
You're total isn't computing correctly mainly because you are changing the first item of your recorded values: intScoreList[0] = intScore;. By altering it, you are interfering with the sum.
A much clean operation consists of adding your new data to the array and recomputing the sum.
List<int> intScoreList = new List<int>(20);
decimal decScoreAverage = 0m;
decimal decScoreTotal = 0m;
private void btnAdd_Click(object sender, EventArgs e)
{
int intScore = Convert.ToInt32(txtScore.Text);
int intScoreCount = 0;
intScoreList.Add(intScore);
decScoreTotal = 0;
foreach(int i in intScoreList) {
decScoreTotal += i;
}
decScoreAverage = decScoreTotal / intScoreList.Count;
intScoreCount = inScoreList.Count;
}
Note that this isn't necessarily the most efficient implementation since as the number of values increase, the foreach loop will get more and more expensive. A better approach is to keep track of the current total and average and adjust them with the new value (which you can still add to the list for other purposes if you need).
The average is computed this way:
New_average = old_average * (count-1)/count + new_value /count
And here's the new code:
List<int> intScoreList = new List<int>(20);
decimal decScoreAverage = 0m;
decimal decScoreTotal = 0m;
private void btnAdd_Click(object sender, EventArgs e)
{
int intScore = Convert.ToInt32(txtScore.Text);
int intScoreCount = 0;
intScoreList.Add(intScore);
intScoreCount = inScoreList.Count;
decScoreTotal += intScore;
decScoreAverage = decScoreAverage * (intScoreCount- 1)/intScoreCount + intScore/intScoreCount;
}
Since the loop adds up all the items,
dont' you want
decScoreTotal = 0
before your for loop?

How to tchart x-axis date and time control?

I'm use Teechart version .Net & VS2005.
X-axis of the graph type of date and time, Y-axis was added to the line Series.
I do not want to represent the null value of the x-axis date and time.
---------data table---------------------
----- Teechart x-axis display -----------
The red line is cursor tool. I set the value of the 'follow mouse = true'.
Cursor tool indicates to text a date and time value of x-axis. shows the time not in the data table. Following values ​​18:23:49 shows the 18:23:50 example. I want to express to the x-axis value for date and time of the data table.
my code:
private void TeeChartSet()
{
Steema.TeeChart.Styles.Line line = new Steema.TeeChart.Styles.Line();
TChart1.Series.Add(line);
line.XValues.DateTime = true;
TChart1.Axes.Bottom.Increment = Steema.TeeChart.Utils.DateTimeStep[(int)Steema.TeeChart.DateTimeSteps.OneSecond];
line.Stairs = true;
TChart1.Series[i].XValues.DataMember = "SetTime";
TChart1.Series[i].YValues.DataMember = "Park Brk Pres Sw1";
TChart1.Series[i].DataSource = Datatable;
TChart1.Axes.Bottom.Labels.DateTimeFormat = "HH:mm:ss";
Steema.TeeChart.AxisLabelStyle.PointValue;
}
private void cursor1_Change(object sender, CursorChangeEventArgs e)
{
TChart1.Invalidate();
DateTime Time = DateTime.FromOADate(e.XValue);
sli_CursorTime.Text = "Cursor Time : " + Time.ToString("yyyy-MM-dd HH:mm:ss");
}
private void MakeDt() //Make datatable Sample Code
{
DataTable dt = new DataTable();
dt.Columns.Add("SetTime");
dt.Columns.Add("Park Brk Pres Sw1");
DataRow row;
for (int i = 0; i < 10; i++)
{
row = dt.NewRow();
row["SetTime"] = DateTime.Now.AddSeconds(i * 5);
row["Park Brk Pres Sw1"] = 0;
dt.Rows.Add(row);
}
}
Many thanks for your extra information, it has been very useful for us. I have made a code, because you can use it to solve your problem. To make code, I have used annotation tool, cursor tool and series line, where only is shown the values of series point in annotation tool. Also I have changed the DateTimeFormat of series. I have added a line of code to export data values as excel format because you can see the results to change DateTimeFormat and it works in your correct way.
Steema.TeeChart.Tools.CursorTool cursorTool1;
private Steema.TeeChart.Tools.Annotation ann;
private double xval;
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
//Tools
cursorTool1 = new Steema.TeeChart.Tools.CursorTool(tChart1.Chart);
cursorTool1.Style = Steema.TeeChart.Tools.CursorToolStyles.Vertical;
// cursorTool1.Pen.Style = System.Drawing.Drawing2D.DashStyle.Dash;
cursorTool1.FollowMouse = true;
// cursorTool1.OriginalCursor = Cursors.Arrow;
ann = new Steema.TeeChart.Tools.Annotation(tChart1.Chart);
ann.Shape.Pen.Visible = false;
ann.Shape.Shadow.Visible = false;
ann.Shape.ShapeStyle = Steema.TeeChart.Drawing.TextShapeStyle.RoundRectangle;
//Series
Steema.TeeChart.Styles.Line line1 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
line1.XValues.DateTime = true;
line1.DateTimeFormat = "HH:mm:ss";
cursorTool1.Series = line1;
line1.Stairs = true;
line1.XValues.DataMember = "SetTime";
line1.YValues.DataMember = "Park Brk Pres Sw1";
line1.DataSource = GetDataTable();
tChart1.Axes.Bottom.Labels.DateTimeFormat = "HH:mm:ss";
tChart1.Axes.Bottom.Labels.Style = Steema.TeeChart.AxisLabelStyle.PointValue;
tChart1.Export.Data.Excel.Save("C:\\Test1.xls");
//Events
tChart1.AfterDraw += new PaintChartEventHandler(tChart1_AfterDraw);
cursorTool1.Change += new CursorChangeEventHandler(cursorTool1_Change);
tChart1.Draw();
}
//DataTable
private DataTable GetDataTable()
{
DataTable dataTable1 = new DataTable("DataSet");
//Condition to filter
//AddColumns in new Table
DataColumn xval = new DataColumn("SetTime", typeof(DateTime));
DataColumn yval = new DataColumn("Park Brk Pres Sw1", typeof(double));
dataTable1.Columns.Add(xval);
dataTable1.Columns.Add(yval);
DateTime dt = DateTime.Now;
for (int i = 0; i < 10; i++)
{
DataRow newRow = dataTable1.NewRow();
newRow[xval] = dt.AddSeconds(i * 5);
newRow[yval] = 0;
dataTable1.Rows.Add(newRow);
}
return dataTable1;
}
//Calculate Interpolate point
private double InterpolateLineSeries(Steema.TeeChart.Styles.Custom series, int firstindex, int lastindex, double xvalue)
{
int index;
for (index = firstindex; index <= lastindex; index++)
{
if (index == -1 || series.XValues.Value[index] > xvalue) break;
}
// safeguard
if (index < 1) index = 1;
else if (index >= series.Count) index = series.Count - 1;
// y=(y2-y1)/(x2-x1)*(x-x1)+y1
double dx = series.XValues[index] - series.XValues[index - 1];
double dy = series.YValues[index] - series.YValues[index - 1];
if (dx != 0.0) return dy * (xvalue - series.XValues[index - 1]) / dx + series.YValues[index - 1];
else return 0.0;
}
private double InterpolateLineSeries(Steema.TeeChart.Styles.Custom series, double xvalue)
{
return InterpolateLineSeries(series, series.FirstVisibleIndex, series.LastVisibleIndex, xvalue);
}
private void cursorTool1_Change(object sender, Steema.TeeChart.Tools.CursorChangeEventArgs e)
{
xval = e.XValue;
ann.Text = "";
this.Text = e.ValueIndex.ToString();
foreach (Steema.TeeChart.Styles.Series s in tChart1.Series)
{
ann.Text += DateTime.FromOADate(s.XValues[e.ValueIndex]).ToString("HH:mm:ss");
}
}
private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
{
int xs = tChart1.Axes.Bottom.CalcXPosValue(xval);
int ys;
g.Brush.Visible = true;
g.Brush.Solid = true;
for (int i = 0; i < tChart1.Series.Count; i++)
if (tChart1.Series[i] is Steema.TeeChart.Styles.Custom)
{
ys = tChart1.Series[i].GetVertAxis.CalcYPosValue(InterpolateLineSeries(tChart1.Series[i] as Steema.TeeChart.Styles.Custom, xval));
//Draw elipse above cursor tool.
g.Brush.Color = tChart1.Series[i].Color;
//Draw annotation as label above cursor tool.
ann.Top = ys;
ann.Left = xs;
}
}
Could you please, tell us if previous code help you to solve your problem?
I hope will helps.
Thanks,

Calculating average with SelectedIndices

My program reads coordinates(double x,douule y) into ListBox and need to calculate the average of them after choosing them with SelectedIndices and MultiExtended.
The problem is how can I refresh my code with each Multiselection.
As you can see I set SelectedIndices[0] to 0 as default. At the moment my program just making average of the 1st coordinate divided by number of selectedIndices.
If you think about any ways to improve my code I would like to know as well.
Thanks!
private void button3_Click(object sender, EventArgs e)//Average
{
int[] selected = new int[] {points_List.SelectedIndices[0] };
double sumX = 0, sumY = 0; ;
foreach (int iIndex in selected)
{
sumX += points[iIndex].X;
sumY += points[iIndex].Y;
}
averageX = (sumX) / (points_List.SelectedIndices.Count);
averageY = (sumY) / (points_List.SelectedIndices.Count);
label1.Text = "Average is: ";
label1.Text += averageX.ToString();
label1.Text += " ";
label1.Text += averageY.ToString();
}
The correct code will require a cast of SelectedIndices through OfType<T> or Cast<T>. Also, it's convenient to call ToArray to materialize the result to avoid having to compute it twice.
var selectedPoints = points_List.SelectedIndices.
OfType<int>().
Select(i => points[i]).
ToArray();
var averageX = selectedPoints.Average(p => p.X);
var averageY = selectedPoints.Average(p => p.Y);
Final solution, Thanks all.
{
double averageX = 0, averageY = 0;
var selectedPoints = from int i in pointsList.SelectedIndices select points[i];
if (pointsList.SelectedIndices.Count == 0)
{
label1.Text = "Average is 0.000 0.000 ";//default text
return;
}
averageX = selectedPoints.Average(p => p.X);
averageY = selectedPoints.Average(p => p.Y);
label1.Text = "Average X: ";
label1.Text += averageX.ToString();
label1.Text += " Y:";
label1.Text += averageY.ToString();
}

C# for loop on button1_click1, int i seems to be advancing wrong

Trying to get it so that if you left click, it will fill in 4 text boxes, then if you use the dropdownlists and click on it again, it will fill in 4 different text boxes - have to get it to fill a total of 20, 4 at a time.
int carpick, qty, total, i;
protected void Button1_Click1(object sender, EventArgs e)
{
for (i = 0; i != 5; ++i)
{
carpick = 0; qty = 0; total = 0;
{
carpick = Convert.ToInt32(CarpickDD.SelectedItem.Value);
qty = Convert.ToInt32(QTYDD.SelectedItem.Value);
total = ((carpick * qty) + (750 * qty));
Label1.Text = CarpickDD.SelectedItem.Text;
Label2.Text = CarpickDD.SelectedItem.Value;
Label3.Text = QTYDD.SelectedItem.Value;
Label4.Text = Convert.ToString(total);}
if (i != 1)
{
carpick = Convert.ToInt32(CarpickDD.SelectedItem.Value);
qty = Convert.ToInt32(QTYDD.SelectedItem.Value);
total = ((carpick * qty) + (750 * qty));
Label5.Text = CarpickDD.SelectedItem.Text;
Label6.Text = CarpickDD.SelectedItem.Value;
Label7.Text = QTYDD.SelectedItem.Value;
Label8.Text = Convert.ToString(total);
}
}
}
enter code here
Every time you click on the button, your for loop starts at i = 0. Therefore, you are not maintaining any state from each invocation to the next; your button doesn’t “remember” how often you have clicked it before.
That said, you are also not making any use of the variable i inside the loop (except for the if (i != 1)). In other words, your loop currently does the same thing on every button click, and it does the same thing five times for each click. If you want to fill in different text boxes the second time you click on the button, surely it should do something different the second time round?
I think you want this:
int carpick, qty, total, i = 0;
protected void Button1_Click1(object sender, EventArgs e)
{
carpick = Convert.ToInt32(CarpickDD.SelectedItem.Value);
qty = Convert.ToInt32(QTYDD.SelectedItem.Value);
total = ((carpick * qty) + (750 * qty));
switch (i++)
{
case 0:
Label1.Text = CarpickDD.SelectedItem.Text;
Label2.Text = CarpickDD.SelectedItem.Value;
Label3.Text = QTYDD.SelectedItem.Value;
Label4.Text = Convert.ToString(total);
break;
case 1:
Label5.Text = CarpickDD.SelectedItem.Text;
Label6.Text = CarpickDD.SelectedItem.Value;
Label7.Text = QTYDD.SelectedItem.Value;
Label8.Text = Convert.ToString(total);
break;
case 2:
..... etc ....
}
}

Categories

Resources