Situation: I wrote a WinForms application which users access via an RDP. The nature of the application is such that two users cannot run the application at the same time. The problem we're having is that folks will forget to close out of the app, essentially locking other users out.
What I'd like to do is add functionality to automatically close the app after x minutes. I realize that I need to use threading for this since marking time in the main thread would freeze up the app. I don't have a critical need to detect activity/inactivity, but if that's trivial to do, I'd definitely like to know.
Thanks in advance for any assistance!
Assuming you're talking about closing the app from inside the WinForms app itself...use a Timer as suggested by SLaks:
public partial class Form1 : Form
{
private System.Windows.Forms.Timer tmr;
public Form1()
{
InitializeComponent();
tmr = new System.Windows.Forms.Timer();
tmr.Tick += delegate {
this.Close();
};
tmr.Interval = (int)TimeSpan.FromMinutes(10).TotalMilliseconds;
tmr.Start();
}
}
If you wan't to get fancier and close after X minutes of inactivity, then write your own IMessageFilter() that resets a Timer whenever mouse/keyboard activity occurs (WM_LBUTTONDOWN, WM_KEYDOWN, WM_SYSKEYDOWN, etc.). You register your filter with Application.AddMessageFilter() in the Load() event of your Form.
This may help, just put this together, it will close the form 1.5 seconds after the button1 is pressed. you could change this to any time after form load.
public void testc()
{
Timer t = new Timer();
t.Interval = 1500;
t.Tick += new EventHandler(timer_Tick);
t.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
MessageBox.Show("Tick");
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
testc();
}
I wrote a class starting from the Idle_Mind's reply, that create a message with another feature : Opacity
Add a Form to your project and call it VanishingMessage.
Add a text label to the Form, i called it : testo
Add the event PAINT to the form.
Copy and paste this code
When you call the class set the the message and seconds as parameters, like required.
I personally suggest to set the FormBorderStyle to NONE.
public partial class VanishingMessage : Form
{
private System.Windows.Forms.Timer tmr;
private System.Windows.Forms.Timer tmr2;
/// <summary>
/// Shows a message windows. 3 sec is the suggested time
/// </summary>
/// <param name="messageText">Message</param>
/// <param name="vanishingSeconds">Showing time</param>
public VanishingMessage(string messageText, int vanishingSeconds=3)
{
InitializeComponent();
double elapsedTime = 0;
testo.Text = messageText;
double vanishingMilliSeconds = vanishingSeconds * 1000;
// message dimensions
this.Width = testo.Width + 50;
this.Height = testo.Height + 50;
//text position
testo.Location = new Point((this.Width / 2) - (testo.Width / 2), (this.Height/2)-(testo.Height/2));
//first timer
tmr = new System.Windows.Forms.Timer();
tmr.Tick += delegate {
tmr.Stop();
tmr2.Stop();
tmr.Dispose();
tmr2.Dispose();
this.Close();
};
tmr.Interval = (int)TimeSpan.FromSeconds(vanishingSeconds).TotalMilliseconds;
tmr.Start();
//second timer
tmr2 = new System.Windows.Forms.Timer();
tmr2.Tick += delegate {
elapsedTime += 50;
if (elapsedTime >= (vanishingMilliSeconds * 65)/100)
this.Opacity -= 0.05f;
};
tmr2.Interval = (int)TimeSpan.FromMilliseconds(50).TotalMilliseconds;
tmr2.Start();
}
private void VanishingMessage_Paint(object sender, PaintEventArgs e)
{
Graphics g = this.CreateGraphics();
Pen p = new Pen(Color.DarkRed);
SolidBrush sb = new SolidBrush(Color.DarkRed);
Rectangle r = this.DisplayRectangle;
r.Width -= 1;
r.Height -= 1;
g.DrawRectangle(p,r);
}
}
Here how to call the class :
VanishingMessage vm = new VanishingMessage("your message",3);
vm.Show();
Related
I have been trying to run a very simple application that moves a 20 by 20 pixel square 20 pixels to the right on a canvas every second. I am using a dispatchertimer to fire the event every second.
The problem is that the square doesn't move to the right unless I shake the application window (with my mouse), and it occasionally moves on its own (albeit not every second).
I have already tried reinstalling Visual Studio 2017 and installing it on my SSD and HDD, neither seem to fix the issue.
Here is the full code of the application's MainWindow.xaml.cs
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DispatcherTimer timer = new DispatcherTimer();
Rectangle s = new Rectangle();
Point currentPosition = new Point(20, 20);
public MainWindow()
{
InitializeComponent();
timer.Tick += Timer_Tick;
timer.Interval = TimeSpan.FromSeconds(1);
timer.Start();
s.Width = 20;
s.Height = 20;
s.Fill = new SolidColorBrush(Colors.Black);
map.Children.Add(s);
}
public void Timer_Tick(object sender, EventArgs e)
{
RedrawSquare();
}
public void RedrawSquare()
{
map.Children.Clear();
s.Width = 20;
s.Height = 20;
s.Fill = new SolidColorBrush(Colors.Black);
Canvas.SetLeft(s, currentPosition.X += 20);
map.Children.Add(s);
}
}
On the MainWindow.xaml file there is an empty Canvas with the name "map"
Thank you in advance
You don't need to remove and add the Rectangle on each timer tick, or reset its properties each time.
Just increment the value of the Canvas.Left property:
public partial class MainWindow : Window
{
private readonly DispatcherTimer timer = new DispatcherTimer();
private readonly Rectangle s = new Rectangle();
public MainWindow()
{
InitializeComponent();
timer.Tick += Timer_Tick;
timer.Interval = TimeSpan.FromSeconds(1);
timer.Start();
s.Width = 20;
s.Height = 20;
s.Fill = Brushes.Black;
Canvas.SetLeft(s, 0);
map.Children.Add(s);
}
public void Timer_Tick(object sender, EventArgs e)
{
Canvas.SetLeft(s, Canvas.GetLeft(s) + 20);
}
}
The movement would however be much smoother with an animation:
public MainWindow()
{
InitializeComponent();
s.Width = 20;
s.Height = 20;
s.Fill = Brushes.Black;
Canvas.SetLeft(s, 0);
map.Children.Add(s);
var animation = new DoubleAnimation
{
By = 20,
Duration = TimeSpan.FromSeconds(1),
IsCumulative = true,
RepeatBehavior = RepeatBehavior.Forever
};
s.BeginAnimation(Canvas.LeftProperty, animation);
}
You can try setting the DispatcherPriority to Normal.
Instantiate your timer like this:
DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Normal);
EDIT:
Although this somehow fixed the issue (square was moving without the need to move the window), it's apparently still the wrong answer. I don't know much about the DispatcherTimer, but I recall having changed the priority once but I don't remember why. In any case, it might be helpful to someone else.
Hye there I am new to C# and just want to run a timer manually! So i just want to know what I am doing wrong in my code. I just need to display a simple message inside my timer! my code is:
public partial class Form1 : Form
{
System.Timers.Timer time;
public Form1()
{
InitializeComponent();
time = new System.Timers.Timer();
time.Interval = 10;
time.Enabled = true;
time.Start();
}
private void time_Tick(object e, EventArgs ea)
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
}
}
}
Please let me know if i am doing something wrong Thanks in advance!
You forgot to listen to the Elapsed event. Add:
time.Elapsed += new ElapsedEventHandler(time_Tick);
To the initialisation of the timer and it should call the callback function when the timer have elapsed (at the moment 10ms)
Note also that the callback function will be called every 10 ms.
Add time.Stop(); inside the callback function if you wish it to stop run.
Edited:
Maybe it is better to use class System.Windows.Forms.Timer instead of System.Timers.Timer. There you can call your function and also access your Textbox.
Otherwise you will receive an InvalidOperationException by trying to access your Textbox txt in time_Tick.
You don't neet a loop for incrementing your value i. just restart your timer and set the new value. What you are doing now is waiting ONE tick (lasting 1000 ms) and then starting your loop.
For example this could be your method:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private int i = 0;
private Timer time;
public Form1()
{
InitializeComponent();
time = new Timer();
time.Tick += time_Tick;
time.Interval = 1000;
time.Start();
}
private void time_Tick(object e, EventArgs ea)
{
if (i < 100)
{
txt.Text = i.ToString();
i++;
time.Start();
}
}
}
}
I have a sync timer in my app that fires up a function at a given time... now I want to know how much time is left until the next call to that function.
This is my call to the timer:
var syncTime = time.activitylog;
double time = TimeSpan.Parse(syncTime).TotalMilliseconds;
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler(DisplayTimeEvent);
myTimer.Interval = time;
myTimer.Start();
How do I get the time until next call?
Thanks
You can use another timer, and set the Interval of that the value that you want,exactly a part time of the Interval of original timer.
Then start them Simultaneously,I mean at the same time.
UPDATE :
Maybe this code describes my solution better :
public Form1()
{
InitializeComponent();
}
System.Windows.Forms.Timer trOriginal = new System.Windows.Forms.Timer();
System.Windows.Forms.Timer trRemain = new System.Windows.Forms.Timer();
double remain = 0;
private void button1_Click(object sender, EventArgs e)
{
trOriginal.Interval = 1000;
trRemain.Interval = 1;
trOriginal.Tick += new EventHandler(trOriginal_Tick);
trRemain.Tick += new EventHandler(trRemain_Tick);
trOriginal.Start();
trRemain.Start();
}
void trRemain_Tick(object sender, EventArgs e)
{
remain -= trRemain.Interval;
Console.WriteLine("remain MS to next event : " + remain);
}
void trOriginal_Tick(object sender, EventArgs e)
{
remain = trOriginal.Interval;
}
You can use a System.Diagnostics.Stopwatch to keep track of how much time has passed already and restart the Stopwatch with every tick of your Timer.
Stopwatch watch = new Stopwatch();
private void DisplayTimeEvent(object sender, EventArgs e)
{
watch.Restart();
// Whatever is supposed to happen, when the timer ticks
}
Now whenever you want to know how much time is left until the event is fired next, you can do this:
long timeLeft = myTimer.Interval - watch.ElapsedMilliseconds;
I have four buttons that are called "ship1,ship2" etc.
I want them to move to the right side of the form (at the same speed and starting at the same time), and every time I click in one "ship", all the ships should stop.
I know that I need to use a timer (I have the code written that uses threading, but it gives me troubles when stopping the ships.) I don't know how to use timers.
I tried to read the timer info in MDSN but I didn't understand it.
So u can help me?
HERES the code using threading.
I don't want to use it. I need to use a TIMER! (I posted it here because it doesnt give me to post without any code
private bool flag = false;
Thread thr;
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
flag = false;
thr = new Thread(Go);
thr.Start();
}
private delegate void moveBd(Button btn);
void moveButton(Button btn)
{
int x = btn.Location.X;
int y = btn.Location.Y;
btn.Location = new Point(x + 1, y);
}
private void Go()
{
while (((ship1.Location.X + ship1.Size.Width) < this.Size.Width)&&(flag==false))
{
Invoke(new moveBd(moveButton), ship1);
Thread.Sleep(10);
}
MessageBox.Show("U LOOSE");
}
private void button1_Click(object sender, EventArgs e)
{
flag = true;
}
Have you googled Windows.Forms.Timer?
You can start a timer via:
Timer timer = new Timer();
timer.Interval = 1000; //one second
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.Start();
You'll need an event handler to handle the Elapsed event which is where you'll put the code to handle moving the 'Button':
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MoveButton();
}
i have developed media player in WPF.but i did n't get timer for slider in that.how i will get that timer below is the my .cs file code.
i used dispatchertimer for timer.video is seeking but timer is not displaying with video.
seekbar not moving where i clicked in seekbar.plz help me .
thanks in advance.
DispatcherTimer timer;
public TimeSpan duration;
public Window1()
{
InitializeComponent();
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(400);
timer.Tick += new EventHandler(timer_tick);
Loaded += new RoutedEventHandler(Window_Loaded);
}
private void mediaElement1_MediaOpened(object sender, RoutedEventArgs e)
{
if (mediaElement1.NaturalDuration.HasTimeSpan)
{
TimeSpan ts = mediaElement1.NaturalDuration.TimeSpan;
slider1.Maximum = ts.TotalSeconds;
slider1.SmallChange = 1;
slider1.LargeChange = Math.Min(10, ts.Seconds / 10);
}
timer.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
slider1.Value = mediaElement1.Position.TotalSeconds;
}
take a look at this
http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx
You can implement this but you will have to pass references to your controls/window because without having references to your controls, the thread/timer object cannot modify controls (ie text etc).
Hope that helps!
Edit: Sorry I misread, but definately check whether the timer youre using can make changes to your elements