C# Textbox properties do not update - c#

I have a simple form with a text box, a command button and a couple of timers. The only purpose of the form is to advise the user what is happening. The program executes all the code as required EXCEPT for the textbox changes. I know the code to implement the textbox changes is executed because the form and the command button properties change as required.
I have added this.refresh and this.textbox1.refresh to no avail.
I am new to C# and most of the time I do not have Visual Studios available, so your assistance would be most appreciated. I have read other posts on this topic and probably the answer has already been given, but I have not understood the solution.
The simplified code is given below:
//PROGRAM.CS
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using WindowsFormsApplication1;
namespace PostBinaryFile
{
static class Program
{
/// The main entry point for the application.
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1(args));
}
}
}
//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;
using System.IO;
using System.Web;
using System.Net;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
string sUrl;
string sFileName;
string sCorNo;
public Form1(string[] args)
{
sUrl = args[0];
sFileName = args[1];
sCorNo = args[2];
InitializeComponent();
timer1.Enabled = true;
timer1.Start();
timer2.Enabled = true;
timer2.Start();
}
public void PostCode()
{
InitializeComponent();
string sToken;
string sPath;
const string boundary = "----WebKitFormBoundaryePkpFF7tjBAqx29L";
try
{
//Do all general code work here.
//Alter form to show successful post to web
this.button1.Visible = true;
this.button1.Enabled = true;
this.BackColor = System.Drawing.Color.FromArgb(189,194,241);
this.textBox1.Text = sCorNo + " Outlook file saved to FuseDMS."; // this code is executed but is not reflected on the Form
this.textBox1.BackColor= System.Drawing.Color.FromArgb(189,194,241); // this code is executed but is not reflected on the Form
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
timer1.Enabled = false;
PostCode();
}
private void timer2_Tick(object sender, EventArgs e)
{
timer2.Stop();
timer2.Enabled = false;
this.textBox1.Text = "Saving Message " + sCorNo + ".";
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}

As #DavidG pointed out, you should not call InitializeComponent() periodically or even more then once, do it as the first thing in the constructor.
This is because any controls and properties that you add/set from the designer are created and initialized in this method.
Another thing to point out is Timer.Enabled = true and Timer.Start() effectively do the same thing
From: System.Windows.Forms.Timer.Enabled
Calling the Start method is the same as setting Enabled to true. Likewise, calling the Stop method is the same as setting Enabled to false.

Both timers namely timer1 and timer2 fire asynchronously and run on separate threads which are completely independent of each other. Even if timer2's tick event would be setting/refreshing the text appropriately through below code:
this.textBox1.Text = "Saving Message " + sCorNo + ".";
you can never say with guarantee that it will happen only after timer1's tick event has completed the execution of its callback method. In all likelyhood your above code is setting the text property of a dangling text box instance as your InitializeComponent function (being called from timer1's tick event) must be reinstantiating a new instance of all the form controls.
Your call to InitializeComponent function in PostCode method which gets called from tick event of timer1's tick event isn't right as it resets all the instances of form controls to new ones. It should be called only once in the constructor of the form. Just remove that piece of code and you should be good. Your PostCode function should actually look like this after you get rid of that piece of code:
public void PostCode()
{
string sToken;
string sPath;
const string boundary = "----WebKitFormBoundaryePkpFF7tjBAqx29L";
try
{
//Do all general code work here.
//Alter form to show successful post to web
this.button1.Visible = true;
this.button1.Enabled = true;
this.BackColor = System.Drawing.Color.FromArgb(189,194,241);
this.textBox1.Text = sCorNo + " Outlook file saved to FuseDMS."; // this code is executed but is not reflected on the Form
this.textBox1.BackColor= System.Drawing.Color.FromArgb(189,194,241); // this code is executed but is not reflected on the Form
}

Related

Invalid cast only when function called from timer

im trying to do a program that read a string from a website e send it to another. the process to read string for the first works correctly, and also the function to send a string to the other works, but have problem when this function was called from the timer..
here is part of my code:
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.Timers;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using CefSharp.WinForms.Internals;
namespace CodePinger
{
public partial class Form1 : Form
{
public bool login = true;
private static System.Timers.Timer TimerCheck;
public Form1()
{
InitializeComponent();
TimerCheck = new System.Timers.Timer(5000);
TimerCheck.Elapsed += new ElapsedEventHandler(CheckEvent);
TimerCheck.AutoReset = true;
CheckForIllegalCrossThreadCalls = false;
webBrowser1.ScriptErrorsSuppressed = true;
chromiumWebBrowser1.Load("https://firstwebsite.com");
webBrowser1.Navigate("http://secondwebsite.com");
}
private async void CheckEvent(Object source, ElapsedEventArgs e)
{
if (login) {
string script = "document.getElementById('SecondSDISP').innerText;";
JavascriptResponse jr = chromiumWebBrowser1.EvaluateScriptAsync(script).Result;
if (jr.Success)
{
if (jr.Result.ToString().Contains("01"))
{
label2.ForeColor = Color.Red;
label2.Text = jr.Result.ToString();
sendCode(jr.Result.ToString());
}
}
else
{
label2.ForeColor = Color.Black;
label2.Text = "no data";
}
label4.Text = timer.ToString();
}
}
private void button2_Click(object sender, EventArgs e)
{
TimerCheck.Enabled = true;
TimerCheck.Start();
button2.Enabled = false;
}
public void sendCode(string code)
{
string msg = "";
if (code == "1") msg = "1 coda";
else msg = code.ToString() + " code";
var textarea = webBrowser1.Document.GetElementsByTagName("textarea")[0];
textarea.InnerHtml = msg;
textarea.Focus();
var allsvg = webBrowser1.Document.GetElementsByTagName("svg");
foreach (HtmlElement svg in allsvg)
{
if (svg.GetAttribute("className").Contains("-send"))
{
svg.InvokeMember("click");
break;
}
}
}
private void button4_Click(object sender, EventArgs e)
{
sendCode("1");
}
}
}
also after i started the timer, if i click to button4 to test the function, it works correctly. instead of when its called from timer
the error is:
System.InvalidCastException
HResult=0x80004002
Message=Specified cast is not valid.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.UnsafeNativeMethods.IHTMLDocument2.GetLocation()
at System.Windows.Forms.WebBrowser.get_Document()
at CodePinger.Form1.sendCode(String code) in C:\Users\Flynns82\source\repos\CodePinger\Form1.cs:line 105
at CodePinger.Form1.<CheckEvent>d__9.MoveNext() in C:\Users\Flynns82\source\repos\CodePinger\Form1.cs:line 63
the indicated line are:
105) var textarea = webBrowser1.Document.GetElementsByTagName("textarea")[0];
63) sendCode(jr.Result.ToString());
can someone explain me what is the problem?
Most likely your problem is you are trying to access the WebBrowser from a non-STA thread (aka the 'UI Thread')
When you use the button4_click handler your code is running on the STA Thread (by default), however, when a Time Event handler is called back it happens in a different thread (which is not the STA one) thus you will have problems invoking/accessing properties on ActiveX/Components (who reside in the STA thread) if you do not "invoke" back into the STA.
I recommend to take a look to the following SO Question: STA vs MTA for a technical explanation.
For solving the invoke problem look into the following SO Question: Automating the InvokeRequired code pattern
On the other hand the browser exposes a NavigateComplete event, you do not need to have a time checking when the page is loaded, just hook yourself to the event and wait for it after navigate, the DOM will be stable once this event fires.

How can the current barcode scan output the value?

I use a GD4430 handheld scanner from the company Datalogic with the included OPOS driver. With the following code I manage to address the scanner. When I start the program, the scanner becomes active and you can scan. But I can not display the results in a TextBox.
Does anyone see where the error lies?
Visual Studio 2010 C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TestRead
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
axOPOSScanner1.BeginInit();
axOPOSScanner1.Open("USBHHScanner");
axOPOSScanner1.ClaimDevice(0);
axOPOSScanner1.DeviceEnabled = true;
axOPOSScanner1.DataEventEnabled = true;
axOPOSScanner1.PowerNotify = 1; //(OPOS_PN_ENABLED);
axOPOSScanner1.DecodeData = true;
}
void axOPOSScanner1_DataEvent(object sender, AxOposScanner_CCO._IOPOSScannerEvents_DataEventEvent e)
{
textBox1.Text = axOPOSScanner1.ScanDataLabel;
textBox2.Text = axOPOSScanner1.ScanData.ToString();
axOPOSScanner1.DataEventEnabled = true;
axOPOSScanner1.DataEventEnabled = true;
}
}
}
Was not the processing of AxOPOSScanner1.BeginInit() on the source originally in Form1.Designer.cs instead of here?
(I am assuming that the source file name is Form1.cs)
As below(in Form1.Designer.cs):
this.axOPOSScanner1 = new AxOposScanner_CCO.AxOPOSScanner();
((System.ComponentModel.ISupportInitialize)(this.axOPOSScanner1)).BeginInit();
this.SuspendLayout();
There is a possibility that the problem has occurred because you moved it to Form1.cs or calling BiginInit() on both Form1.Designer.cs and Form1.cs.
Or, the following processing does not exist in Form1.Designer.cs, or there is a possibility that the specified function name(axOPOSScanner1_DataEvent) is wrong.
this.axOPOSScanner1.DataEvent += new AxOposScanner_CCO._IOPOSScannerEvents_DataEventEventHandler(this.axOPOSScanner1_DataEvent);
In addition:
What you should do is to temporarily store the return value of all the methods, add a process to determine whether the method was executed normally, likewise It is to read the ResultCode property immediately after setting the property(possibly causing an error) and add processing to judge whether the property setting was done normally.
Also, although not related to DataEvent, PowerNotify setting must be done before DeviceEnabled = true.

Displaying received data from serial port

I have a problem working with the serial data received event handler. Half of the time the data displays on the textbox and half of the time does not. It should be the issue with cross thread operation.
This is my Arduino code:
int Loop = 1;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(Loop);
Loop++;
delay(1000);
}
And here is my C# code:
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;
using System.IO.Ports;
namespace arduino_test
{
public partial class Form1 : Form
{
SerialPort sPort;
public Form1()
{
InitializeComponent();
initialiseArduino();
}
public void initialiseArduino()
{
sPort = new SerialPort();
sPort.BaudRate = 9600;
sPort.PortName = "COM16";
sPort.Open();
//sPort.DataReceived += new SerialDataReceivedEventHandler(sPort_DataReceived);
}
void sPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string data = sp.ReadExisting();
displayMessage(data);
}
public void displayMessage(string data)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(displayMessage), new object[] { data });
return;
}
textBox1.Text = data;
}
private void button1_Click(object sender, EventArgs e)
{
while (true)
{
string data = sPort.ReadLine();
textBox1.Text = data;
}
}
}
}
When i use the serial data received event handler, it gives me that problem even after invoking.
So i tried running a same thread operation by clicking a button and it works perfectly fine.
Can anybody advise me on what have i done wrong?
The obvious difference and the cause of your problem is the two different way you do this. You use ReadExisting() in your DataReceived event handler but ReadLine() in your Click event handler.
ReadExisting() just doesn't do what you hope it does, you only get 1 or 2 characters. Whatever is "existing", never much since the DataReceived event fires quickly and modern desktop computers are very fast. Then the event fires again and you read another 1 or 2 chars. Your TextBox only shows whatever came last.
Use ReadLine() instead.
You might want to update displayMessage method with
public void displayMessage(string data)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(displayMessage), new object[] { data });
return;
}
**textBox1.Text = textBox1.Text + data;**
}
In this way you'll never clear the textBox1 content and you'll have all values.
Please take in consideration (depends by your data) that your incoming data could contain control chars or other things that could not be nicely shown in textbox control.

Why is the program form not loading when accessing file?

With the below code, I've tested it out and the loading of the form works fine standalone, but when the program goes to check if a file exists, the form doesn't load properly and I'm at a loss as to what to do. Is there another method of checking to see if a file exists that I could use in this instance?
EDIT I've made a new 'startup' form to run the file exists check, but it still doesn't work. Again the form loads, but the contents of the form don't and the form itself freezes.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Timers;
using System.IO;
using System.Collections;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Diagnostics;
using System.Windows.Input;
namespace program1
{
public partial class Startup : Form
{
public Startup()
{
InitializeComponent();
}
private void Startup_Load(object sender, EventArgs e)
{
notifyIcons norm = new notifyIcons();
Settings set = new Settings();
set.Show();
string curFile = Environment.CurrentDirectory + "\\age.txt";
if (File.Exists(curFile))
{
norm.Show();
this.Close();
}
else
{
set.Show();
for (;;)
{
if (File.Exists(curFile)) norm.Show(); this.Close();
Application.DoEvents();
}
}
}
}
}
I have no idea what this code is supposed to do.. but I can tell you why its not working.
while (ageFileExists)
That is never false. Therefore, your loop will continually loop... forever. You need to set it false somehow in the loop. I have no idea what sort of rules govern that though.
The reason the form doesn't load is because the loop never exits.. and so the message loop that makes the window do anything can never continue processing window messages.
If you can give more context around what you're trying to do I could help you with a proper solution. As it stands though, I can only see the problem.
while(ageFileExists)
{
if (File.Exists(curFile)) ageFileExists = true;
set.WindowState = FormWindowState.Normal;
}
If that file exists you have an infinite loop. You never set ageFileExists to false and that loop does nothing at all. And where does that label go? I seriously doubt you need to be using goto. Your code doesn't make much sense as it stands.
By using the following code in the main form, it seemed to work a treat! I think the critical part was Application.DoEvents();
Thanks for all of your assistance
InitializeComponent();
set.Show();
set.WindowState = FormWindowState.Minimized;
string curFile = Environment.CurrentDirectory + "\\age.txt";
if (File.Exists(curFile)) goto Labelx;
set.WindowState = FormWindowState.Normal;
for (; ; ) { Application.DoEvents(); if (File.Exists(curFile)) break; }
set.WindowState = FormWindowState.Minimized;
Labelx:TextReader reader = File.OpenText(Environment.CurrentDirectory + "\\age.txt");

Trying to make a very simple speech recognition windows form project

I followed a very basic tutorial (forgot the link) and it all seems straightforward, but I don't seem to be getting the output I want. Here is my main form class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Speech.Recognition;
namespace OralNotes.Alpha
{
public partial class MainForm : Form
{
private SpeechRecognitionEngine recognitionEngine;
public MainForm()
{
InitializeComponent();
recognitionEngine = new SpeechRecognitionEngine();
recognitionEngine.SetInputToDefaultAudioDevice();
recognitionEngine.SpeechRecognized += (s, args) =>
{
foreach (RecognizedWordUnit word in args.Result.Words)
{
if (word.Confidence > 0.8f)
txtNotes.Text += word.Text + " ";
}
txtNotes.Text += Environment.NewLine;
};
recognitionEngine.LoadGrammar(new DictationGrammar());
}
private void btnStart_Click(object sender, EventArgs e)
{
recognitionEngine.RecognizeAsync();
}
private void btnStop_Click(object sender, EventArgs e)
{
recognitionEngine.RecognizeAsyncStop();
}
}
}
And you probably don't need this, but here it is anyway:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace OralNotes.Alpha
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}
I click start and talk, and nothing happens.
UPDATE*
ok so this is working, if I adjust this line
if (word.Confidence > 0.8f)
to a lower number I get a word or two in. Not transcribing sentences or anything, is there a way to make this have better recognition?
It seems that the engine that you are using returns a confidence value on every word it hears.
I suspect that the confidence values range from 0-1. Which means that if you lower the value from 0.8 you are making the engine more tolerant to words. Maybe it is the quality of your mic?

Categories

Resources