What I am doing:
I am receiving a string of data every second constantly from a serial port. I am processing it and also displaying this string on the rich text box.
Problem:
I want the user to go through the old strings and copy any, but user can't do it because data is coming every second and auto-scrolling occurs.
My desired solution:
I am thinking to have a check-box 'pause'. when user checks it updating of rich text box stops. and user can go in history and copy a string. but in the mean while I don't want to stop the incoming strings from the serial port as I am doing other things as well with the incoming strings.
So when user uncheck 'pause' checkbox, all the strings which had arrived earlier while user had checked' pause' checkbox also appear on rich text box along with new ones.
is there a way to do it ?
Suppose that when you check the Pause button then every incoming text is appended to a StringBuilder instead of the RichTextBox. When the user uncheck the Pause button you copy everything from the StringBuilder to the RichTextBox
// Assume that these are somewhere globals of your forms
RichTextBox rtb = new RichTextBox();
CheckBox chkPause = new CheckBox();
StringBuilder sb = new StringBuilder();
protected void chkPause_CheckedChanged(object sender, EventArgs e)
{
if(!chkPause.Checked)
{
rtb.AppendText = sb.ToString();
// Do not forget to clear the buffer to avoid errors
// if the user repeats the stop/go cycle.
sb.Clear();
}
else
{
// Start a timer to resume normal flow after a timer elapses.
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
t.Interval = GetSuspensionMilliseconds();
t.Tick += onTick;
t.Start();
}
}
protected void onTick(object sender, EventArgs e)
{
if (chkPause.Checked)
{
// Set to false when the timing elapses thus triggering the CheckedChanged event
chkPause.Checked = false;
System.Windows.Forms.Timer t = sender as System.Windows.Forms.Timer;
t.Stop();
}
}
now in the point where the incoming data is passed to the RichTextBox you could add
....
string incomingData = ReceiveDataFromSerialPort();
if(chkPause.Checked)
sb.AppendLine(incomingData);
else
rtb.AppendText = incomingData;
Related
I have a GridView (RadGridView by Telerik) with a CheckBox column for multiple row selection. Each row represents a document and I need to be able to select multiple documents to apply them a digital signature.
Actually if only one document is selected, I open a new aspx page inside a popup and that page calls the DigitalSignature service (a web application listening on specific port) that open a Wacom screen wich waits for the signature on the Wacom tablet. When the user sign or close the window, the popup close and the GridView is updated.
I need to do this inside a foreach loop for every selected row.
The problem is that now I call ScriptManager.RegisterStartupScript with unique name but they're opened all togheter at the same time but I want to open one by one.
Possibly without using jQuery or 3rd party libraries.
I'm using .NET Framework v3.5.
Actual code:
foreach (SelectedDocument selectedDoc in SelectedDocuments)
{
Documento doc;
try
{
// Open document
doc = session.Load<Document>(Convert.ToInt64(selectedDoc.ID));
if (doc != null)
{
// Get the file...
// Do some stuff...
// Set query string
string queryString = string.Format("Sign.aspx?fileNameToSign={0}&reader={1}&view={2}&docid={3}&userid={4}",
pathQueryString, certificate, "0", selectedDoc.ID, UserId);
string urlDownload = Page.ResolveClientUrl(string.Format("~/Path/To/Folder/{0}", queryString));
string script = string.Format("loadDownload('{0}','_blank',600,600);", urlDownload);
// Open Wacom window
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "DocID" + selectedDoc.ID, script, true);
}
}
}
Why don't you set an on off check to see that the document has been signed, before the loop gets to the next document, it should wait (Use await to go on with the loop)
See example:
Start by creating a helper method to generate a task that will be completed when a button is clicked:
public static Task WhenClicked(this Button button)
{
var tcs = new TaskCompletionSource<bool>();
EventHandler handler = null;
handler = (s, e) =>
{
tcs.TrySetResult(true);
button.Click -= handler;
};
button.Click += handler;
return tcs.Task;
}
After that, you can easily wait until either 2 seconds (or more) have passed, or the button is clicked:
public async void Bar()
{
this.button.Focus();
this.button.BackColor = Color.Green;
await Task.WhenAny(Task.Delay(2000), button.WhenClicked());
// now the loop continues and the button changes its color
this.button.BackColor = Color.White;
}
Hi everyone this is my first question to stackoverflow and sorry for my English. I searched for a week and couldn't find the solution. I am working on a project which uses RFID antenna and tags . A machine reads the tags and produces tag id like bcbc 0000 or abab 1111 ... Every id points a unique product like shirt , panth etc.This program is a product counter. My form application uses this id's matches with the products and counts them. When program gets a shirt id I want to increase "shirt count label" on the form at the reading time. I wrote 2 different programs and both didn't update the label.
my codes :
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Interval = 2000;
aTimer.Start();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
reading part is below;
reader.Connect(SolutionConstants.ReaderHostname);
Settings settings = reader.QueryDefaultSettings();
settings.Report.IncludeFastId = true;
settings.Report.IncludeAntennaPortNumber = true; // WS
settings.Antennas.GetAntenna(1).MaxTransmitPower = true;
settings.Antennas.GetAntenna(1).MaxRxSensitivity = true;
settings.Antennas.GetAntenna(2).MaxTransmitPower = true;
settings.Antennas.GetAntenna(2).MaxRxSensitivity = true;
...... and other settings here....
// Apply the newly modified settings.
reader.ApplySettings(settings);
// Assign the TagsReported event handler.
// This specifies which method to call
// when tags reports are available.
reader.TagsReported += OnTagsReported;
// Start reading.
reader.Start();
in OntagsReported() function i do some controls and the important part is
tagList.Add(tag.Epc.ToString()); // adds tags to tagList.
timer function ;
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
for (int i = 0; i < tagList.Count; i++)
{
if (!usedTags.Contains(tagList[i]))
{
//MessageBox.Show("");
label1.Text = "Text Updated.";
//productCounter(tagList);
usedTags.Add(tagList[i]);
}
}
}
Everything is working . Program goes last if control. If I write there a messageBox it shows that but on the next line label does not change. Thanks for help :)
System.Windows.Forms.Timer instead of System.Timers.Timer could help you.
System.Timers.Timer fires event in the non-UI thread,
so you should not access UI controls directly in the event handlers.
Seems like you need to marshal the call to the UI thread.
label1.BeginInvoke(new Action(() => label1.Text = "Text Updated"));
I have the following piece of code:
class NotepadCloneNoMenu : Form
{
protected TextBox txtbox;
public NotepadCloneNoMenu(string a)
{
Text = "Notepad Clone No Menu";
txtbox = new TextBox();
txtbox.Parent = this;
txtbox.Dock = DockStyle.Fill;
txtbox.BorderStyle = BorderStyle.None;
txtbox.Multiline = true;
txtbox.ScrollBars = ScrollBars.Both;
txtbox.AcceptsTab = true;
txtbox.AppendText(a);
txtbox.AppendText("\n");
}
}
class program1
{
public static void Main()
{
string result = "abc";
while(true)
{
Application.Run(new NotepadCloneNoMenu(result));
}
}
}
I want to continuously appending the string result to the textbox so it looks like this:
abc
abc
abc
so on and so forth. However, every time I called this:
Application.Run(new NotepadCloneNoMenu(result));
It will reset the textbox. Is there anyway I can update the textbox continuously? I am fairly new to C# so this is quite confusing to me.
thanks,
Phuc Pham
First of all, you're continuously closing and opening an application. That's why it resets. If you want to run an infinite loop, you probably want to run it inside your application proper.
In your application code, use some event (maybe a timer would suit you) to append text to the textBox. Like this:
public someEventOnTheForm (object sender, EventArgs e)
{
txtBox.Text += "Notepad Clone to Menu";
}
There's two more things to take into account: first, if you don't have a stoping condition, this will just keep filling memory until you run out of it.
Second, windows forms run on only one thread by default. You'll be using that thread to update the textbox, so while it's appending text, the form itself will be unusable. It'll probably blank out during the event if it starts taking long. You'll need a second thread to handle the event if you want your form to be usable.
My problem is that the program speaks before the form gets displayed.
Here's the load block:
/********************
* *
* Start Game *
* *
********************/
private void Battleship_Load(object sender, EventArgs e)
{
// Interface housekeeping
lblStatus.Font = new Font("HandelGotDLig", 18);
// fill computer board
game.buildBoards();
human = game.Human;
computer = game.Computer;
shot = game.Initialize(ref human, ref shot);
//set up displays
gbComputerHistory.Visible = false;
gbHumanHistory.Visible = false;
gbShot.Visible = false;
lblStatus.Text = "Choose who starts";
gbStart.Visible = true;
// display human board
DisplayBoard(picHuman, human, false);
// display computer ships
DisplayBoard(picComputer, computer, false);
this.Refresh();
#if SPEECH
Say("Welcome to BATTLESHIP! Prepare to Lose!");
Say("Choose who starts first.");
#endif
}
I suspect I could bury it in the paint event, but then I'd have to keep track of whether it has spoken already.
I don't want it speaking every time the form is repainted.
Try adding the speech code to the Form_Shown event. This event is raised whenever the form is shown to the user (when they can actually see it). From MSDN:
The Shown event is only raised the first time a form is displayed; subsequently minimizing, maximizing, restoring, hiding, showing, or invalidating and repainting will not raise this event.
i have a timer that changes a label's text each tick. For some reson, it stop and does not continue looping. Why?
private int count = 0;
private void timer1_Tick(object sender, EventArgs e)
{
string[] arr4 = new string[3]; // 4
arr4[0] = "one";
arr4[1] = "two";
arr4[2] = "three";
if (count == 4)
{
count = 0;
}
toolStripStatusLabel1.Text = arr4[count];
count++;
}
Also, when my form loads, the label's text is blank. Then it goes to arr4[0]. When it loops again, the text starts at arr[0]. Why is the text blank first, and how do i fix it?
Looks like your original question was answered in the comments. I'll answer your second question from the comments.
Your timer1_Tick event doesn't execute immediately when your program starts. The first time it executes is after 5000ms, in your case. So the label will show blank at first, then change to the value of arr4[0]. If you don't want that, you could:
set the value of the label in the designer at design time
set the value of the label in the constructor at run time
pull the creation of the array out of the timer tick event so you're not recreating it every 5 seconds, make it a class variable, and create it in the constructor and then set the label to arr4[0] immediately after creating it