I am new to C#. Basically I want to implement an auto save function using a timer. May I know how do I have to implement it, so that the text will get saved automatically every 5 seconds?
SaveFileDialog saveFile1 = new SaveFileDialog();
saveFile1.DefaultExt = "*.rtf";
saveFile1.Filter = "RTF Files|*.rtf";
if (saveFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
saveFile1.FileName.Length > 0)
{
txtb.SaveFile(saveFile1.FileName, RichTextBoxStreamType.PlainText);
I can save the file but how do I auto save it?
Just use a timer with an interval of 5000ms
Timer tmr = New Timer;
tmr.Interval = 5000;
Now call your timer in the Form_Load event or whereever you want to call it the first time. After that, just use the Tick event of the timer (Note: The first time you call the SAVEFILEDIALOG, make sure that you store the location in some variable so that you can keep on reusing it to save the text file which will eliminate the need of using the SAVEFILEDIALOG again and again):
String pathOfFile;
private sub FirstTimeSaveIt_Click // the button that saves it first
if (saveFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
saveFile1.FileName.Length > 0)
{
pathOfFile = saveFile1.FileName
txtb.SaveFile(saveFile1.FileName, RichTextBoxStreamType.PlainText);
}
private void tmr_Tick()
{
tmr.Stop();
txtb.SaveFile(pathOfFile, RichTextBoxStreamType.PlainText);
tmr.start();
}
Related
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;
I am developing software that adds if a button is clicked 5 times, a variable is incremented by '1'
IF A then B++
everything is good, but now I want the system to reset its counter if that 5 times did not happen within 10 seconds. I.e the speed of clicking matters.
If I click too slow, the increment should not happen even though I clicked 5 times as it exceeds that 10 secs period.
Any suggestion?
This could be done much nicer but it should work:
DateTime time = new DateTime();//time of first click
int counter = 0;
void button_click(object sender, EventArgs e)
{
if(counter == 0)
{time = DateTime.Now}
else if(counter == 5)
{
if( DateTime.Now.Subtract(time).Duration().Seconds <= 10)
{/*Do some cool stuff*/}
else
{counter = -1;}
}
counter++;
}
I'd do something like this:
const int ClicksRequired = 5;
readonly TimeSpan ClickTimeSpan = new TimeSpan(0, 0, 10);
Queue<DateTime> _clicks = new Queue<DateTime>();
private void clickTarget_MouseUp(object sender, MouseEventArgs e)
{
var currentTime = DateTime.Now;
_clicks.Enqueue(currentTime);
if (_clicks.Count == ClicksRequired)
{
var firstTime = _clicks.Dequeue();
if (currentTime - firstTime <= ClickTimeSpan)
{
MessageBox.Show("Hello World!");
_clicks.Clear();
}
}
}
I use Queue to keep track of clicks because you don't know which mouse click will actually be the first click until you have five clicks in the time window. You need to know the time of the fifth click back in time and that click changes with each subsequent click.
I use MouseUp instead of Click because Click might not fire the correct number of times if clicks occur within the system double-click interval (because those get routed to DoubleClick).
I have linked the import button with a media element so i can get the song to play.
// Create OpenFileDialog
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
// Set filter for file extension and default file extension
dlg.DefaultExt = ".txt";
dlg.Filter = "WAV Files (*.wav)|*.wav|MP3 Files (*.mp3)|*.mp3|MP4 Files (*.mp4)|*.mp4|WMA Files (*.wma)|*.wma|SWA (*.swa)|*.swa";
// Display OpenFileDialog by calling ShowDialog method
Nullable<bool> result = dlg.ShowDialog();
// Get the selected file name and display in a TextBox
if (result == true)
{
// Open document
meMedia1.Source = new Uri(dlg.FileName);
meMedia1.Play();
//txtFileLocation.Text = filename;
Now, the sound plays but what I want to do is link a slider so they can skip some of the song and also a label above the slider so that it read how long into the song it is. This is how my application looks now to give you an idea.
http://i.stack.imgur.com/sVtrd.png
Thank You.
EDIT : Got the seek to change the song position but I still cant get it manually moving to the time of the song, for example if I skip to the middle of the song, and let the song finish my slider will still be in the middle and I want it to be at the end.
One approach is to create a DispatcherTimer that ticks every 200-800ms (depending on your preference for update speed) that syncs the slider to the player's current Position. That code might look similar to this:
// In the class members area
private DispatcherTimer _timer = null;
// In your constructor/loaded method
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromMilliseconds(500);
_timer.Tick += _timer_tick;
// Timer's tick method
void _timer_tick(object sender, EventArgs e)
{
// Convert duration to an integer percentage based on current position of
// playback and update the slider control
TimeSpan ts = meMedia1.NaturalDuration.TimeSpan;
int percent = int( meMedia1.Position / ts.Seconds * 100 );
mySliderControl.Value = percent;
}
Note that this assumes you have a Slider whose Min is 0 and Max is 100. You can bump it up to 0-1000 (and change the math accordingly) to get finer granularity. This also doesn't allow the slider to push user interaction back to the player, but gives you an idea of one way to get the opposite. You can add an event handler to the Slider such that when the user begins interacting, this _timer is stopped ( _timer.Stop() ) so updates to the media position stop updating the slider and instead start doing your slider -> media position updates instead. Then when the user lets go of the slider, turn the _timer back on ( _timer.Start() ).
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
How might I be able to change the Text property of a label depending on what the current time is?
Thank you
To clarify:
I'd like the text of a label to read open between 10am and 5pm and then read closed between 5:01 pm to 9:59am.
Use a Timer. In the Timer.Tick handler, modify the label's Text property using a simple if/else statement based on DateTime.Now.
int hour = DateTime.Now.Hour;
if (hour >= 10 && hour < 17)
//Open 10:00am through 4:59pm
LabelStatus.Text = "Open";
else
//Closed 5:00pm through 9:59am
LabelStatus.Text = "Closed";
Below is a method to do this using a separate thread that updates the label. This way the thread will run in the background, and constantly check that the label is at the correct status. Make sure when closing the form you stop the thread, either by using Thread.Abort() and catching the exception that I believe is always thrown, or by adding a flag as the condition in the while loop, and lower the flag to stop the thread.
As long as no other object accesses the label, there shouldn't be any need to lock any part of the thread.
public delegate void DelLabelText(Label l, string s);
public DelLabelText delLabelText;
public Form1()
{
InitializeComponent();
delLabelText = Label_Text;
// Initialize text
lblOpenStatus.Text = "Closed";
// Create and start thread
Thread threadUpdateLabel = new Thread(UpdateLabel_Threaded);
threadUpdateLabel.Start();
}
// Thread function that constantly checks if the text is correct
public void UpdateLabel_Threaded()
{
while (true)
{
Thread.Sleep(5000);
// 24 hour clock so 17 means 5
if ((DateTime.Now.Hour >= 10 && DateTime.Now.Hour < 17) || (DateTime.Now.Hour == 17 && DateTime.Now.Minute == 0 && DateTime.Now.Second == 0))
{
if (lblOpenStatus.Text.ToLower() == "closed")
{
Label_Text(lblOpenStatus, "Open");
}
}
else
{
if (lblOpenStatus.Text.ToLower() == "open")
{
Label_Text(lblOpenStatus, "Closed");
}
}
}
}
// Set the text using invoke, because text is changed outside of main thread
public void Label_Text(Label label, string text)
{
if (label.InvokeRequired)
{
label.Invoke(delLabelText, new object[] { label, text });
}
else
{
label.Text = text;
}
}
Add a timer to your form and set its interval to 1000 ms..
Declare a invisible TextBox having the Miliseconds of the current time updated by the Timer on Every Tick..
now on the TextBox.TextChanged event of the Textbox Add a Function to Convert the Milliseconds to Time...
Next Method is add a Timer and set the interval to 1 ms...
Update the time from there..
Next Method, is adding a BackgroundWorker and use it as a Timer to update the Time...
If you find any of the above methods useful...Comment and I will post codes! :)