Stopping focus changed event being handled multiple times in one second - c#

I have a focus changed event handler (uia) on a background MTA thread for updating a list of elements for the current active window which gets fired multiple times in one second when changing active window. I am trying to make it to go once and then wait for one second before handling any other events. Problem at the minute is that the timer is started but never triggered? I guess there is a better way of doing this? A code example would be great.
public void HandleFocusChangedEvent(IUIAutomationElement sender)
{
// A focus changed event has been sent by the the active window or some descendant of it.
// Check that this event hasn't arrived around the time we're removing the event handler on shutdown.
if (!_fAddedEventHandler)
{
return;
}
// All the event handler needs to do is notify the main UI thread that the
// list of elements should be refreshed to make sure it's showing the most current list.
// We only want to do this once every second So use a timer/counter
if (focusChangedCounter == 0)
{
controllerDispatcher.BeginInvoke(_focusChangedEventHandlerDelegate);
focusChangedCounter = 1;
if (focusChangedBufferTimer == null)
{
focusChangedBufferTimer = new System.Windows.Forms.Timer();
focusChangedBufferTimer.Tick += new EventHandler(focusChangedBufferTimer_Tick);
focusChangedBufferTimer.Interval = 1000;
focusChangedBufferTimer.Start();
}
}
}
private void focusChangedBufferTimer_Tick ( object sender, EventArgs e)
{
focusChangedCounter = 0;
focusChangedBufferTimer.Stop();
focusChangedBufferTimer = null;
}

Try this: With each event trigger, reset the timer.
public partial class Form1 : Form
{
Timer t = new Timer();
public Form1()
{
InitializeComponent();
t.Interval = 1000;
t.Tick += ((ss, ee) => {
t.Enabled = false;
focusChangedCounter = 0;
focusChangedBufferTimer.Stop();
focusChangedBufferTimer = null;
});
}
private void HandleFocusChangedEvent(object sender, EventArgs e)
{
t.Enabled = false;
t.Enabled = true;
}
}

Related

C# Winforms: Simulate user clicks(start- wait for data collection - stop)

I am writing up a C# application using Winforms, and I need to collect some data based on my selection from a comboBox. I also have a start button that enables data collection, and a stop button that halts the data collection.
This is what I am capable of doing right now:
Measure all data from all channels by switching my selection on the comboBox (one channel at a time). The process goes like: select a channel- start button click - wait for data collection - stop button click
But here is what I want to do in code:
Select a channel - start button click - wait for data collection - stop button click
switch to next channel - start button click -wait for data collection - stop button click
................
repeat this process until done.
My question is: what should I adopt to achieve this?
I have been trying to use startButton.PerformClick( ) to enabling the buttons, however, I need to stop for a few seconds in between starting and stopping to wait for data collection.
You may ask why because this is very inefficient, but for some reason the DLL from the third party cannot collect data from all channels at the same time. So i have to manually switch my channel selection from the comboBox in order to collect all data at one go.
Please let me know if you have any suggestions.
private void timer_Tick(object sender, EventArgs e)
{
startButton.PerformClick();
}
private void timer2_Tick(object sender, EventArgs e)
{
stopButton.PerformClick();
}
private void checkAll_CheckedChanged(object sender, EventArgs e)
{
int i = 0;
while (i != 40) //there are a total of 40 channels
{
System.Windows.Forms.Timer mytimer = new System.Windows.Forms.Timer();
mytimer.Interval = 5000;
System.Windows.Forms.Timer mytimer2 = new System.Windows.Forms.Timer();
mytimer2.Interval = 7000;
mytimer.Start();
mytimer.Tick += new EventHandler(timer_Tick);
mytimer2.Start();
mytimer2.Tick += new EventHandler(timer2_Tick);
physicalChannelComboBox.SelectedIndex = i;
i++;
Thread.Sleep(5000);
}
}
Here is a simple routine shell that should help you. This uses a timer to poll if the data is complete (checking a boolean, which is currently set to true for testing). In your case you could probably just set the timers tick value to be the delay you want. If you have a way of knowing when the data is done being collected for the channel, that would be more preferable. This code runs standalone so you can test and configure it before starting to integrate it into your existing code. All it requires is a a listbox for viewing the logs.
public partial class DataCollectorForm : Form
{
private Timer timer = new Timer();
private int numberOfChannels = 40;
private int currentChannelNumber = 0;
private DateTime routineStartTime;
private DateTime routineStopTime;
private DateTime channelStartTime;
private DateTime channelStopTime;
public DataCollectorForm()
{
InitializeComponent();
timer.Interval = 250;
timer.Tick += Timer_Tick;
DataCollectionRoutineStart();
}
private void Timer_Tick(object sender, EventArgs e)
{
// Need to check if data collection for this channel is complete..
//
var isDoneCollectingData = true;
if (isDoneCollectingData)
{
ChannelDataCollectionStop();
currentChannelNumber++;
if (currentChannelNumber >= numberOfChannels)
{
DataCollectionRoutineComplete();
}
else
{
ChannelDataCollectionStart();
}
}
}
public void DataCollectionRoutineStart()
{
routineStartTime = DateTime.Now;
Log("Data Collection Routine Start");
currentChannelNumber = 0;
ChannelDataCollectionStart();
timer.Start();
}
private void ChannelDataCollectionStart()
{
channelStartTime = DateTime.Now;
Log("Data Collection Start : channel " + currentChannelNumber);
}
private void ChannelDataCollectionStop()
{
channelStopTime = DateTime.Now;
Log("Data Collection Stop : channel " + currentChannelNumber + " : elapsed " + (channelStopTime - channelStartTime));
}
private void DataCollectionRoutineComplete()
{
routineStopTime = DateTime.Now;
timer.Stop();
Log("Data Collection Routine Complete : elapsed " + (routineStopTime - routineStartTime));
}
private void Log(string msg)
{
loggingListBox.Items.Add(msg);
}
}

How to implement Timer Elapsed Event on UserInterface thread in Xamarin Android

Am implementing a System Timer on Xamarin Android and i have a problem with the elapsed event not raising a dialog box with the message "Time is up" when the countdown is Over...
I figured the problem might be not implementing the event on the User Interface thread so i need your help accomplishing that...
Here is my code for the Timer
class SecondActivity : AppCompatActivity
{
int counter = 10;
private System.Timers.Timer _timer;
private int _countSeconds;
protected override void OnCreate(Bundle savedInstanceState)
{
_timer = new System.Timers.Timer();
//Trigger event every second
_timer.Interval = 1000;
_timer.Elapsed += OnTimedEvent;
//count down 5 seconds
_timer.Enabled = true;
_countSeconds = 5;
}
private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e)
{
_countSeconds--;
if (_countSeconds == 0) {
_timer.Stop();
Switch switch1 = this.FindViewById<Switch>(Resource.Id.switch2);
Android.App.AlertDialog.Builder dialog = new Android.App.AlertDialog.Builder(this);
Android.App.AlertDialog alert = dialog.Create();
alert.SetTitle("");
alert.SetMessage("Simple Alert");
alert.SetButton("OK", (c, ev) =>
{
// Ok button click task
});
switch1.Checked = false;
}
I just want the Elapsed event handler to display an alert dialog box when the variable count down equals zero, Thank You
After the first comment pointed me to a related question i found the method to implement the user thread and it now works as intended to display the alert dialog...
private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e)
{
//This is how to make the Timer callback on the UI
RunOnUiThread(() =>
{
_countSeconds--;
if (_countSeconds == 0)
{
Switch switch1 = this.FindViewById<Switch>(Resource.Id.switch2);
Android.App.AlertDialog.Builder dialog = new Android.App.AlertDialog.Builder(this);
Android.App.AlertDialog alert = dialog.Create();
alert.SetTitle("Its over");
alert.SetMessage("Simple Alert");
alert.SetButton("OK", (c, ev) =>
{
// Ok button click task
});
alert.Show();
switch1.Checked = true;
}
});
}

Set simple timeout

I've checked the other questions in SO for timeout in C#, but since I'm a beginner, I don't really know how to implement them into my code. They look too sophisticated.
I have a text box and I added a click event. Upon click, user copies the content of the text box to the clipboard. To make the copy process noticeable to the user, I change the back color of the text box. Once the content is copied, I want to change the back color of the text box back to normal. So I need to set a timeout.
private void IDBox_Click(object sender, EventArgs e)
{
CopyToClipboard((TextBox)sender);
}
private void CopyToClipboard(TextBox textBox)
{
if (textBox.Text != "")
{
textBox.BackColor = System.Drawing.Color.MistyRose;
Clipboard.SetText(textBox.Text);
// set 200ms timeout and then change BackColor
//textBox.BackColor = System.Drawing.SystemColors.Window;
}
}
How can I set a timeout? An example would be great.
Not sure if that fits to your requirements (beginner?), but that will do a simple blinking by using Task and invoking text color changing back after delay:
textBox.BackColor = Color.MistyRose;
Task.Run(() =>
{
Thread.Sleep(200); // delay
this.BeginInvoke((MethodInvoker)delegate
{
textBox.BackColor = SystemColors.Window;
});
});
Use a Timer and change colour back in the Elapsed event.
Quick and dirty (untested) code to get you started:
private void CopyToClipboard(TextBox textBox)
{
if (textBox.Text != "")
{
textBox.BackColor = System.Drawing.Color.MistyRose;
Clipboard.SetText(textBox.Text);
// Create a timer with a 1 second interval.
System.Timers.Timer aTimer = new System.Timers.Timer(1000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
// Only tick one time
aTimer.AutoReset = false;
// Start timer
aTimer.Enabled = true;
}
}
private void OnTimedEvent(Object source, ElapsedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate
{
textBox.BackColor = System.Drawing.SystemColors.Window;
});
}
Supposed you have a textbox named test you can use the dispatcher timer in WPF or the Windows forms timer if you are working in windows forms.
test.Background = new SolidColorBrush(Colors.MistyRose);
Clipboard.SetText(test.Text);
var dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler((s, x) =>
{
dispatcherTimer.Stop();
test.Background = new SolidColorBrush(Colors.White);
});
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
dispatcherTimer.Start();

C# Timer inside a property

I'm trying to implement a timer for a checkbox. The binding for the checkbox is done using the CaptureColorBind property. When ever I click the capture color checkbox (captureColor = true), it needs to be checked for 5 seconds and then checkbox needs to be unchecked. I'm trying to print the datetime before and after the timer to verify. Its printing the before time properly, but the datetime I print in the elapsed event handler gets printed n times depending on the number of times I click the capture color checkbox. That is the first time I click, it prints the date and time once, the second time I click, it prints twice and so on. Not sure what I'm doing wrong.
private System.Timers.Timer timer = new System.Timers.Timer();
public bool CaptureColorBind
{
get
{
return this.captureColor;
}
set
{
this.captureColor = value;
if (captureColor == true)
{
Console.WriteLine(DateTime.Now.ToString());
Console.WriteLine();
timer.Elapsed += new ElapsedEventHandler(capturecolor_timer);
timer.Interval = 5000;
timer.Enabled = true;
}
if (null != this.PropertyChanged)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("CaptureColorBind"));
}
}
}
// Timer for capturecolor checkbox
private void capturecolor_timer(object sender, ElapsedEventArgs e)
{
timer.Enabled = false;
this.captureColor = false;
//this.colorCheckbox.IsChecked = false;
Console.WriteLine(DateTime.Now.ToString());
Console.WriteLine();
if (null != this.PropertyChanged)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("CaptureColorBind"));
}
}
You are adding a new event handler every time the value is set. You should only add it once.
Try adding the event handler in the object's constructor so it only gets set once, and just re-enabling the timer when the property is set.
private System.Timers.Timer timer = new System.Timers.Timer();
public MyObject()
{
timer.Elapsed += new ElapsedEventHandler(capturecolor_timer);
timer.Interval = 5000;
}

Pausing a BackgroundWorker from another method

I have a program that is continuously running.
When I start the program, I have a BackgroundWorker (InitialStart.cs):
BackgroundWorker recordingSyncWorker = new BackgroundWorker();
recordingSyncWorker.DoWork += new DoWorkEventHandler(RecordingSyncCheck);
recordingSyncWorker.WorkerSupportsCancellation = false;
recordingSyncWorker.WorkerReportsProgress = false;
recordingSyncWorker.RunWorkerAsync();
void RecordingSyncCheck(object sender, DoWorkEventArgs e)
{
cHandler ch = new cHandler();
Timer theTimer;
int seconds = 1;
if (taskSeconds != null && taskSeconds != "")
seconds = Convert.ToInt32(taskSeconds);
int milliseconds = seconds * 1000;
theTimer = new Timer(10000);
theTimer.Elapsed += new ElapsedEventHandler(ch.SyncMethod);
theTimer.Interval = milliseconds;
theTimer.Enabled = true;
}
And I have two methods in another class (cHandler.cs):
SyncMethod(object source, System.Timers.ElapsedEventArgs e)
{
// random code
}
private string SDCardCheck(object whatever)
{
//more code
}
SDCardCheck gets called thru WCF, so it's like there is another instance of cHandler.cs running. Is there a way for me to pause the BackgroundWorker when I call SDCardCheck?
Don't use a BackgroundWorker just to start a timer. Starting a timer is not a long running operation; it can be done directly from the UI thread.
Your other method can disable the timer to stop it from firing, and then enable it again to allow it to continue firing, in order to effectively pause its execution.

Categories

Resources