I'm a tad new to C# so please bear with me!
I am writing a program to send code via RS232 to a home made telescope mount.
The issues I have at the moment is hopefully very simple (But quite difficult for me!)
As an example say I have a button, I want to execute a loop when the left mouse button is held down, (which will be a continuous stream of 232 data), then when the left mouse button is released I need the loop to stop and to execute another line of code.
I sincerely hope that information I have given is enough and somebody is kind enough to help me along (I have searched the internet for answers believe me!)
Many thanks.
Hook into the MouseDown and MouseUp events on the button. The MouseDown event should spawn a thread, or signal to the thread to begin executing the loop. The MouseUp event should signal to the thread to stop executing the loop.
Something like this:
public class InterruptibleLoop
{
private volatile bool stopLoop;
private Thread loopThread;
public void Start() {
// If the thread is already running, do nothing.
if (loopThread != null) {
return;
}
// Reset the "stop loop" signal.
stopLoop = false;
// Create and start the new thread.
loopThread = new Thread(LoopBody);
loopThread.Start();
}
public void Stop() {
// If the thread is not running, do nothing.
if (loopThread == null) {
return;
}
// Signal to the thread that it should stop looping.
stopLoop = true;
// Wait for the thread to terminate.
loopThread.Join();
loopThread = null;
}
private void LoopBody() {
while (!stopLoop) {
// Do your work here
}
}
}
Method 1:
First create a timer with the interval set to the frequency you want it to send the data. And send the data in the tick event. Create an event for the button's mouse down event and the buttons' mouse up event. In the mouse down event, start the timer. In the mouse up event, stop the timer.
Method 2:
Instead of starting a timer on the mouse down event, start a new thread where you do a continuous loop of data sending. Stop the thread on the mouse up event.
namespace Scope_Project_Ver_2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// *** Output data timer ***
otimer.Interval = 50;
// otimer.Interval = isendFreq;
otimer.Tick += new EventHandler(otimer_Tick);
// *** Input data timer ***
// itimer.Interval = 601; <- to be unchecked
// itimer.Tick += new EventHandler(itimer_Tick); <- to be unchecked
}
public int b1,b2,b3,b4,b5;
public string sb1, sb2, sb3, sb4, sb5;
public int ivorSpeed;
public string svorSpeed;
public int ihorSpeed;
public string shorSpeed;
public int isendFreq;
private void sendDataB_Click(object sender, MouseEventArgs e)
{
if (sendDataCB.Checked)
{
sendDataCB.Checked = false;
if (otimer.Enabled)
otimer.Stop();
}
else
{
sendDataCB.Checked = true;
if (!otimer.Enabled)
otimer.Start();
}
}
void otimer_Tick(object sender, EventArgs e)
{
SerialPort port = new SerialPort(
"COM1", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.Write("Q"); // Q
port.Write(sb1); // 1
port.Write(sb2); // 2
// Binary stuff // Ver Speed Binary 3
byte[] bverbinary = new byte[1];
byte verbinary = 0;
verbinary = Byte.Parse(svorSpeed);
bverbinary[0] = verbinary;
port.Write(bverbinary, 0, bverbinary.Length);
// End of Binary stuff for Ver Speed
// Binary stuff // Hor Speed Binary 4
byte[] bhorbinary = new byte[1];
byte horbinary = 0;
horbinary = Byte.Parse(shorSpeed);
bhorbinary[0] = horbinary;
port.Write(bhorbinary, 0, bhorbinary.Length);
port.Write(sb5); // Movement 5
port.Close();
}
private void vorSpeed_ValueChanged(object sender, EventArgs e)
{
// MessageBox.Show((this.vorSpeed.Value).ToString());
this.Text = "You changed the Vertical Speed to " + vorSpeed.Value;
ivorSpeed = (int)vorSpeed.Value;
svorSpeed = ivorSpeed.ToString();
}
private void horSpeed_ValueChanged(object sender, EventArgs e)
{
// MessageBox.Show((this.horSpeed.Value).ToString());
this.Text = "You changed the Horizontal Speed to " + horSpeed.Value;
ihorSpeed = (int)horSpeed.Value;
shorSpeed = ihorSpeed.ToString();
}
private void scopeUp_MouseDown(object sender, MouseEventArgs e) // Scope Up On
{
b1 = 2;
b2 = 0;
b5 = 1;
sb1 = b1.ToString();
sb2 = b2.ToString();
sb3 = b3.ToString();
sb4 = b4.ToString();
sb5 = b5.ToString();
}
private void scopeUp_MouseUp(object sender, MouseEventArgs e) // Scope Up Off
{
}
private void scopeRight_MouseDown(object sender, MouseEventArgs e)
{
b1 = 1;
b2 = 2;
b5 = 1;
sb1 = b1.ToString();
sb2 = b2.ToString();
sb3 = b3.ToString();
sb4 = b4.ToString();
sb5 = b5.ToString();
}
private void scopeRight_MouseUp(object sender, MouseEventArgs e)
{
}
private void scopeDown_MouseDown(object sender, MouseEventArgs e)
{
b1 = 2;
b2 = 1;
b5 = 1;
sb1 = b1.ToString();
sb2 = b2.ToString();
sb3 = b3.ToString();
sb4 = b4.ToString();
sb5 = b5.ToString();
}
private void scopeDown_MouseUp(object sender, MouseEventArgs e)
{
}
private void scopeLeft_MouseDown(object sender, MouseEventArgs e)
{
b1 = 0;
b2 = 2;
b5 = 1;
sb1 = b1.ToString();
sb2 = b2.ToString();
sb3 = b3.ToString();
sb4 = b4.ToString();
sb5 = b5.ToString();
}
private void scopeLeft_MouseUp(object sender, MouseEventArgs e)
{
}
private void scopeStop_Click(object sender, EventArgs e)
{
b1 = 0;
b2 = 0;
b5 = 0;
sb1 = b1.ToString();
sb2 = b2.ToString();
sb3 = b3.ToString();
sb4 = b4.ToString();
sb5 = b5.ToString();
}
private void sendFreq_ValueChanged(object sender, EventArgs e)
{
this.Text = "You changed the send Freq to " + sendFreq.Value + " m/s";
isendFreq = (int)sendFreq.Value;
}
}
}
Related
I am using Visual Studio .Net Framework to create a slideshow that operates on its own after clicking the "play" button. My current issue is that I do not know how to go about making the application go to the next file in the document after the video has ended. At the moment I have it setup for the user to select a time period for how long they want each image displayed, but I would rather have this feature automated.
This is my current code :
{
public partial class TVDisplay : Form
{
// Time f3 = new Time();
public TVDisplay()
{
//f3.Show();
InitializeComponent();
//both listview and listbox clear at initilize//
listBox1.Items.Clear();
listView1.Items.Clear();
//xml file from first application is read for department information, and that path and department are placed in textbox3 to be read by the listbox//
var xd = new XmlDocument();
string pathz = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filepath = pathz + #"\Assigned_Television.xml";
xd.Load(filepath);
// var list = xd.GetElementsByTagName("Television");
textBox3.Text = xd.GetElementsByTagName("Path")[0].InnerText;
}
protected override bool ProcessDialogKey(Keys keyData)
{
//when esacpe is pressed, the display screen is windowed instead of fullscreen//
if (Form.ModifierKeys == Keys.None && keyData == Keys.Escape)
{
FormBorderStyle = FormBorderStyle.Sizable;
WindowState = FormWindowState.Normal;
return true;
}
return base.ProcessDialogKey(keyData);
}
//Page load//
private void Form1_Load(object sender, EventArgs e)
{
axWindowsMediaPlayer1.stretchToFit = true;
axWindowsMediaPlayer1.uiMode = "none"; //disables the play, pause, etc. buttons at the bottom of the windows media player//
listView1.Items.Clear(); //clears listview items//
Repopulate(); //calls repopulate function//
refreshtimer.Interval = 5 * 60 * 1000;
//timer for when images need to be displayed//
Timer tmr = new Timer();
int result = int.Parse(textBox2.Text);
tmr.Interval = result * 60 * 1001;
tmr.Tick += new EventHandler(timer1_Tick);
tmr.Start();
}
private void Repopulate()
{
foreach (var d in System.IO.Directory.GetFiles(textBox3.Text))
{
var dirName = new DirectoryInfo(d).Name;
listView1.Items.Add(dirName);
}
foreach (ListViewItem item in listView1.Items)
{
item.Selected = true;
listBox1.Items.Add(item.Text);
}
}
//hidden button that acts as a "play" button, taking url from textbox 1, playing the video, and looping it until it is time for the next image//
private void button1_Click(object sender, EventArgs e)
{
// MessageBox.Show(textBox4.Text);
axWindowsMediaPlayer1.URL = textBox4.Text;
axWindowsMediaPlayer1.Ctlcontrols.play();
axWindowsMediaPlayer1.settings.setMode("loop", true);
}
// timer that clicks button one//
private void timer1_Tick(object sender, EventArgs e)
{
button1.PerformClick();
}
private void axWindowsMediaPlayer1_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
}
//when the tvdisplay is shown, start button is clicked and button 1 (play button) is clicked//
private void TVDisplay_Shown(object sender, EventArgs e)
{
startbutton.PerformClick();
button1.PerformClick();
}
//hidden behind windows media player//
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Timer tmr = new Timer();
int result = int.Parse(textBox2.Text);
tmr.Interval = result * 60 * 1000;
//int result = int.Parse(textBox3.Text);
// tmr.Interval = 1 * 60 * 1000;
//tmr.Interval = 180000;
tmr.Tick += new EventHandler(timer2_Tick);
tmr.Start();
//textBox2.Clear();
var path = textBox3.Text;
textBox4.Text = path + listBox1.SelectedItem.ToString();
}
private void refreshtimer_Tick(object sender, EventArgs e)
{
listBox1.BeginUpdate();
int x = listBox1.SelectedIndex;
listBox1.Items.Clear();
listView1.Items.Clear();
Repopulate();
//selects the first index once files are repopulated//
listBox1.SelectedIndex = x;
listBox1.EndUpdate();
}
//hidden behind windows media display//
private void startbutton_Click(object sender, EventArgs e)
{
startbutton.Enabled = false;
timer3.Interval = 10000; //time in milliseconds
timer3.Tick += timer3_Tick;
timer3.Start();
//startbutton.Enabled = false;
if(listBox1.Items != null)
{
MessageBox.Show("There is no content entered for display.", "Error");
Application.Exit();
}
else {
listBox1.SelectedIndex = (listBox1.SelectedIndex + 1) % listBox1.Items.Count;
}
}
private void timer2_Tick(object sender, EventArgs e)
{
startbutton.PerformClick();
}
private void timer3_Tick(object sender, EventArgs e)
{
startbutton.Enabled = true;
timer3.Stop();
}
}
}
Image/Video is displayed by Windows Media Player.
I have two forms, form1 and credentials. I want the data in my textbox (can be filled by user) to be transferred to the data grid view in form1.
Also, in form1, I want the data in my labels to be also transferred into the data grid view, which is also in form1. The labels I want to be transferred are: score, timer, level
I have tried and research for multiple solutions, yet none can really solve my problem. however, I tried to combine the solutions from websites and here is what i can do that kind of make sense to me. following are the codes for form1 and credentials.
form1 source code:
public partial class Form1 : Form
{
Snake mySnake;
Board mainBoard;
Rewards apples;
string mode;
Timer clock;
int duration; //How long the game has been running
int speed = 500; //500ms
int score;
int highscore;
int level;
public Form1()
{
InitializeComponent();
//button2.Text = Char.ConvertFromUtf32(0x2197);
//You don't have to worry about the auto-size
this.AutoSize = true; //The size of the Form will autoadjust.
boardPanel.AutoSize = true; //The size of the panel grouping all the squares will auto-adjust
//Set up the main board
mainBoard = new Board(this);
//Set up the game timer at the given speed
clock = new Timer();
clock.Interval = speed; //Set the clock to tick every 500ms
clock.Tick += new EventHandler(refresh); //Call the refresh method at every tick to redraw the board and snake.
duration = 0;
score = 0;
highscore = 0;
level = 1;
modeLBL.Text = mode;
gotoNextLevel(level);
scoresDGV.ColumnCount = 4;
scoresDGV.Columns[0].HeaderText = "Name";
scoresDGV.Columns[1].HeaderText = "Level";
scoresDGV.Columns[2].HeaderText = "Score";
scoresDGV.Columns[3].HeaderText = "Timer";
scoresDGV.AllowUserToAddRows = false;
scoresDGV.AllowUserToDeleteRows = false;
scoresDGV.MultiSelect = false;
scoresDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
scoresDGV.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
private void refresh(Object myObject, EventArgs myEventArgs)
{
//increment the duration by amount of time that has passed
//this method is called every speed millisecond
duration += speed;
timerLBL.Text = Convert.ToString(duration / 1000); //Show time passed
//Check if snke is biting itself. If so, call GameOver.
if (mySnake.checkEatItself() == true)
{
GameOver();
}
else if (apples.checkIFSnakeHeadEatApple( mySnake.getHeadPosition()) == true)
{
score += apples.eatAppleAtPostion(mySnake.getHeadPosition());
scoreLBL.Text = Convert.ToString(score);
if (apples.noMoreApples() == true)
{
clock.Stop();
level++;
levelLBL.Text = Convert.ToString(level);
gotoNextLevel(level);
MessageBox.Show("Press the start button to go to Level " + level, "Congrats");
}
else
{
//Length the snake and continue with the Game
mySnake.extendBody();
}
}
if (score > highscore)
{
highscoreLBL.Text = Convert.ToString(highscore);
}
}
private void startBTN_Click(object sender, EventArgs e)
{
clock.Start();
}
private void pauseBTN_Click(object sender, EventArgs e)
{
clock.Stop();
}
private void restartBTN_Click(object sender, EventArgs e) //snapBTN
{
duration = 0;
mySnake.draw();
}
private void backBTN_Click(object sender, EventArgs e)
{
// hides the form from the user. in this case, the program hides the HowToPlay form
this.Hide();
MainMenu mM = new MainMenu();
mM.ShowDialog();
this.Close();
}
private void GameOver()
{
clock.Stop();
MessageBox.Show("Your time taken is " + duration/1000 + " seconds. Bye Bye", "Game Over");
this.Close();
addCurrentScoresToDatabase();
//updateScoreBoard();
}
private void modeLBL_Click(object sender, EventArgs e)
{
}
private void addCurrentScoresToDatabase()
{
Credentials c = new Credentials();
c.ShowDialog();
}
}
credentials source code:
public partial class Credentials : Form
{
public static string SetValueForName = "";
public Credentials()
{
InitializeComponent();
}
private void saveBTN_Click(object sender, EventArgs e)
{
SetValueForName = enternameTB.Text;
Form1 frm1 = new Form1();
frm1.Show();
}
private void cancelBTN_Click(object sender, EventArgs e)
{
}
}
Because part of your code is made in the designer (and not shown here in your post) it is difficult to understand how it works. I assume you have a simple dialog form which is shown in your form1
Credentials is shown modal. So if you have some properties in your credentials dialog, you may data transfer via the properties.
private void addCurrentScoresToDatabase()
{
Credentials c = new Credentials();
// initialize c here
c.ShowDialog();
// read data from c here
}
If you want get data from the credential dialog while it is shown, you should use events.
https://learn.microsoft.com/en-us/dotnet/standard/events/
If you want to transfer score, timer, level to datagridview and transfer Name from credentials to datagridview, you can refer to the following code:
Code in Form1:
int index;
public void AddScore_Click(object sender, EventArgs e)
{
index = scoresDGV.Rows.Add();
scoresDGV.Rows[index].Cells[1].Value = label1.Text;
scoresDGV.Rows[index].Cells[2].Value = label2.Text;
scoresDGV.Rows[index].Cells[3].Value = label3.Text;
Credentials c = new Credentials();
c.FormClosed += c_FormClosed;
c.Show();
}
void c_FormClosed(object sender, FormClosedEventArgs e)
{
scoresDGV.Rows[index].Cells[0].Value = Credentials.SetValueForName;
}
Code in Credentials:
public partial class Credentials : Form
{
public static string SetValueForName = "";
public Credentials()
{
InitializeComponent();
}
private void saveBTN_Click(object sender, EventArgs e)
{
SetValueForName = enternameTB.Text;
this.Close();
}
}
Here is the test result:
Ive got this timer that will count for 10 seconds. I want a progressbar to show that, how long it will take etc, it might be 10 seconds now but it could be dynamic in the future.
private void button1_Click_1(object sender, EventArgs e)
{
dataGridView1.DataSource = null;
labelCapture.Text = " ";
buttonCapture.Enabled = false;
labelCapture.Text = "Measuring for 10 seconds...";
timerCapture.Interval = 10000;
timerCapture.Enabled = true;
UseWaitCursor = true;
timerCapture.Start();
Program.ModalForm.progressBarFormModal.Maximum = 10;
timerCapture.Tick += new EventHandler(timerCapture_Tick);
capture = true;
myFormModal.ShowDialog(this); // Where I open the ModalForm
}
and my event is as follows
void timerCapture_Tick(object sender, EventArgs e)
{
if (Program.ModalForm.progressBarFormModal.Value != 10)
{
Program.ModalForm.progressBarFormModal.Value++;
}
else
{
timerCapture.Stop();
}
}
how the modal Form gets closed
private void TickToggle(object sender, EventArgs e)
{
capture = false;
timerCapture.Stop();
UseWaitCursor = false;
timerCapture.Enabled = false;
myFormModal.Close(); // Close the modal form after timer is done
}
Does anyone seen an error that I might have overlooked?
I am having a problem . I want to use if statement to check if a button is clicked. For Example:
public void button1_Click(object sender, EventArgs e)
{
while (1)
{
...
...
...
if (Button2 == clicked)
{
break;
}
}
}
But it's not working like this, because the ".click" can only be on the left side of "+=" or "-=". Any idea how i can check if Button2 is clicked?
the code is loking like this: and i want to check button2 to stop the "programm".
the check for the Button2 is nearly at the end of the code ;)
public void button1_Click(object sender, EventArgs e)
{
Random rnd = new Random();
int EmFilterPos;
int ExFilterPos;
string String1;
int[] EmLB = new int[126];
int[] ExLB = new int[126];
int LBEmAnzahl = 0;
int LBEmTot = 0;
int LBExAnzahl = 0;
int LBExTot = 0;
UInt32 C_Zyklen;
UInt32 Zyklen;
Roche.DetectionControl2.Device_Filterwheels.ELBPowerState LB_On = Roche.DetectionControl2.Device_Filterwheels.ELBPowerState.LBOn;
Roche.DetectionControl2.Device_Filterwheels.ELBPowerState LB_Off = Roche.DetectionControl2.Device_Filterwheels.ELBPowerState.LBOff;
Roche.DetectionControl2.Device_Filterwheels.fiweGetLBResponse LightBarrier;
string Text = String.Format("Filterrad-Dauertest\r\nGestart am {0:d} um {0:t}\r\n\r\n", DateTime.Now);
System.IO.File.WriteAllText(#"TestLogFile\Filterrad_Dauertest1.txt", Text);
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweInitFilter();
System.Threading.Thread.Sleep(50);
while (Zyklen <= 20)
{
for (int q=1;q<8;q++)
{
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweMove(q,q);
System.Threading.Thread.Sleep(50);
Zyklen++;
}
for (int w=0;w<7;w++)
{
ExFilterPos = rnd.Next(1,8);
EmFilterPos = rnd.Next(1,8);
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweMove(ExFilterPos,EmFilterPos);
System.Threading.Thread.Sleep(50);
Zyklen++;
}
C_Zyklen = Zyklen;
if ((C_Zyklen % 2) < 14)
{
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweInitFilter();
System.Threading.Thread.Sleep(50);
using (System.IO.StreamWriter file = new System.IO.StreamWriter (#"TestLogFile\Filterrad_Dauertest1.txt", true))
{
file.Write("Init bei: ");
String1 = String.Format("{0,7}",Zyklen);
file.Write(String1);
file.Write(file.NewLine);
}
ExFilterPos = 60;
EmFilterPos = 60;
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweRawMove(ExFilterPos,EmFilterPos);
System.Threading.Thread.Sleep(50);
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweSetLB(LB_On);
while (EmFilterPos != -60)
{
LightBarrier = Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweGetLB();
if (LightBarrier.LBEm == Roche.DetectionControl2.Device_Filterwheels.ELBState.LBbright)
{
LBEmAnzahl++;
LBEmTot += EmFilterPos;
}
if (LightBarrier.LBEx == Roche.DetectionControl2.Device_Filterwheels.ELBState.LBbright)
{
LBExAnzahl++;
LBExTot += ExFilterPos;
}
ExFilterPos--;
EmFilterPos--;
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweRawMove(ExFilterPos,EmFilterPos);
}
EmFilterPos = LBEmTot / LBEmAnzahl;
ExFilterPos = LBExTot / LBExAnzahl;
using (System.IO.StreamWriter file = new System.IO.StreamWriter (#"TestLogFile\Filterrad_Dauertest1.txt", true))
{
file.Write("Nullstelle Mittelposition Em-Filter: ");
file.Write(EmFilterPos);
file.Write(file.NewLine);
file.Write("Nullstelle Mittelposition Ex-Filter: ");
file.Write(ExFilterPos);
file.Write(file.NewLine);
file.Write(file.NewLine);
}
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweSetLB(LB_Off);
}
if (Button2 == clicked) // or something like this
break;
}
using (System.IO.StreamWriter file = new System.IO.StreamWriter (#"TestLogFile\Filterrad_Dauertest1.txt", true))
{
file.Write("Beendet am {0:d} um {0:t}\r\n", DateTime.Now);
}*/
}
Hm...
bool b1clicked = false, b2clicked = false;
public void button2_Click(object sender, EventArgs e)
{
b2clicked = true;
}
public void button1_Click(object sender, EventArgs e)
{
b1clicked = true;
if (b1clicked && b2clicked)
{
//...
}
}
Beside the weird behavior you want..and since you are not using Threads, you have the following options:
Local functions (.Net > 4.7)
private void B_Click(object sender, EventArgs e)
{
bool clickFlag = false;
void Click(object sender2, EventArgs e2)
{
clickFlag = true;
}
b2.Click += Click;
while (!clickFlag)
{
Thread.Sleep(1);
}
b2.Click -= Click;
//Continue with your stuff
}
Threads
Thread newThread;
private void Button1_Click()
{
newThread = new Thread(YourBreakableProcess);
newThread.Start();
}
private void Button2_Click()
{
newThread.Join();
}
private void YourBreakableProcess()
{
//Your breakable process
}
Async methods.
I hope you find a solution. Cheers.
Edit:
Since what you want is to interrupt the process of whatever you are doing, the only option you have is Local fuctions as shown above, if you are not tied to a specific framework version.
BackgroundWorker and check in every step if the button 2 was pressed with the flag thing mentioned in other answer.
Threads, and make a thread.Join when the button 2 is pressed.
Edit 2:
Updated answer with Threads, I will recommend that if you go with this option it is much better to use a BackgroundWorker instead as you will have the whole control of the process breaking it only in the place where it would be fine to break it.
You can achieve this using a flag variable. Declare and initialize flag value to false.On button2 click change flag value to true as follows,
private bool flag= false;
private void button2_Click(object sender, EventArgs e)
{
flag= true;
}
public void button1_Click(object sender, EventArgs e)
{
//Use flag to check whether button 2 has clicked or not
if (flag)
{
}
else
{
}
}
Hi I am trying to use the queue function in my program for a mini game that receives X,Y,Z acceleration from an accelerometer.
However I don't know where I should or how I should declare the queue to make it accessible in two separate event handler.
As you can see I tried multiple attempts and declaring it in both the private event handlers was my last attempt.
Any help is appreciated. Thanks!
Here's my current code:
public Form1()
{
InitializeComponent();
ConnectedComPortUpdate();
serialPort1.DataReceived += DataReceivedHandler;
comboBox1.DropDown += comboBox1_DropDown;
}
private void comboBox1_DropDown(object sender, EventArgs e)
{
ConnectedComPortUpdate();
}
private void Clock_Tick(object sender, EventArgs e)
{
int xAccel;
int yAccel;
int zAccel;
Queue<int> myXQueue = new Queue<int>();
Queue<int> myYQueue = new Queue<int>();
Queue<int> myZQueue = new Queue<int>();
while( myXQueue.Count!=0 && myYQueue.Count!=0 && myZQueue.Count!=0 );
{
xAccel = myXQueue.Dequeue();
yAccel = myYQueue.Dequeue();
zAccel = myZQueue.Dequeue();
this.BeginInvoke(new EventHandler(delegate
{
XAccel.Text = xAccel.ToString("000");
YAccel.Text = yAccel.ToString("000");
ZAccel.Text = zAccel.ToString("000");
}));
}
}
private void ConnectedComPortUpdate()
{
//Clears COM List
comboBox1.Items.Clear();
//Accesses System Port Information and Adds it to the ComboBox
comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames().ToArray());
//Selects the last and "first" device
try
{
comboBox1.SelectedIndex = 0;
}
catch (ArgumentOutOfRangeException)
{
MessageBox.Show("Please plug in your tiny stick");
comboBox1.Text = (" ");
}
}
private void button1_Click(object sender, EventArgs e)
{
if (!serialPort1.IsOpen)
{
try
{
serialPort1.PortName = comboBox1.Text;
serialPort1.Open();
comboBox1.Enabled = false;
butPortState.Text = "Disconnect";
MessageBox.Show(String.Format("You selected port '{0}'", serialPort1.PortName));
}
catch
{
MessageBox.Show("Please select a serial port from the drop down list");
}
}
else
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
comboBox1.Enabled = true;
butPortState.Text = "Connect";
}
}
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
int currentDataByte = 0;
int byteToRead;
int xAccel = 0;
int yAccel = 0;
int zAccel = 0;
Queue<int> myXQueue = new Queue<int>();
Queue<int> myYQueue = new Queue<int>();
Queue<int> myZQueue = new Queue<int>();
while (serialPort1.IsOpen && serialPort1.BytesToRead != 0)
{
try
{
byteToRead = serialPort1.ReadByte();
}
catch
{
byteToRead = 0;
}
if (byteToRead == 255)
{
currentDataByte = 0;
}
else
{
currentDataByte++;
switch (currentDataByte)
{
case 1:
myXQueue.Enqueue(byteToRead);
xAccel = byteToRead;
break;
case 2:
myYQueue.Enqueue(byteToRead);
yAccel = byteToRead;
break;
case 3:
myZQueue.Enqueue(byteToRead);
zAccel = byteToRead;
break;
}
}
}
}
}
}
You would need the queues to be declared at the class/instance level:
// These can now be used in all event handlers...
Queue<int> myXQueue = new Queue<int>();
Queue<int> myYQueue = new Queue<int>();
Queue<int> myZQueue = new Queue<int>();
public Form1()
{
InitializeComponent();
ConnectedComPortUpdate();
serialPort1.DataReceived += DataReceivedHandler;
comboBox1.DropDown += comboBox1_DropDown;
}
private void comboBox1_DropDown(object sender, EventArgs e)
{
ConnectedComPortUpdate();
}
private void Clock_Tick(object sender, EventArgs e)
{
int xAccel;
int yAccel;
int zAccel;
I don't think the answer to this question (or even the question itself) is C# specific necessarily. Consider the question "Where should I declare variable X" The answer is almost always "In the narrowest scope possible that's accessible every place that needs to use variable X"
In your case, the answer may be "At the class level"
Alternatively, if you were to program in a more functional style the answer may be "Reconsider the structure of the program so that X can be passed as a parameter to the functions that need it". Most C# event handler have a place where you can stick a "user state" object so that it can be passed along from event source to event handler.
The answer would be the same in C, C++, java, etc.
(Perhaps this should be a comment, but I'm afraid it's a bit long)