I have an application. If the application is not being used for a certain amount if time, it should hide. When application is hidden and we mouse-over the icon, it should be restored.
How can I do this? Thanks in advance.
You have to define a timer in your application that will count the time when mouse is not over the form/window. Then just hide your application.
Download WPF NotifyIcon
And handle MouseOver event, that will show Form/Window
EDIT:
If you do not need to minimize application to tray and hide window keeping it on desktop -> use the same algorithm, but do not hide the window, just set transparency to 0% or 10%. When mouse is over - set transparency to 100%.
Like JesseJames said, use a timer to measure the inactive time of the application and hide it after an amount of time. Re-activate it when the mouse is hovered over the NotifyIcon. Here's a sample WindowsForms solution that does the job:
private Timer _timer;
private int _ticks;
public Form1()
{
_timer = new Timer { Interval = 1000, Enabled = true };
_timer.Tick += TimerTick;
Activated += Form1_Activated;
MouseMove += Form1_MouseMove;
//notifyIcon1 is an icon set through the designer
notifyIcon1.MouseMove += NotifyIcon1MouseMove;
}
protected void TimerTick(object sender, EventArgs e)
{
//After 5 seconds the app will be hidden
if (_ticks++ == 5)
{
WindowState = FormWindowState.Minimized;
Hide();
_timer.Stop();
_ticks = 0;
}
}
protected void NotifyIcon1MouseMove(object sender, MouseEventArgs e)
{
WindowState = FormWindowState.Normal;
Show();
_ticks = 0;
_timer.Start();
}
protected void Form1_MouseMove(object sender, MouseEventArgs e)
{
_ticks = 0;
}
Perhaps there might exist a cleaner solution, I don't know, but it gets you on the way. Same principle will go for WPF, only the code will be slightly different. Hope this helps!
To see if the user has made any input you can use a similar approach like this one. To get your application visible again you need a way to get the global mouse and maybe keyboard input, to do this you can use hooks, you can find one solution for that here. And if the hook is triggered it really just depends on what kind of UI you are using, but calling specific hide or show methods should be suffice.
Related
I have project with several hundreds of buttons, created dynamically within for-loop. I also have timer to update toolstripstatuslabel (labelClock) with current time every second:
static System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
...
timer.Tick += new System.EventHandler(timer_Tick);
...
private void timer_Tick(object sender, EventArgs e)
{
labelClock.Text = DateTime.Now.ToString();
}
Here's the problem: last clicked button will be focused, of course. So if I scroll page down, everytime timer ticks page scrolls up (or down), so the focused button becomes visible.
How can I prevent that?
Stupid solution (won't work, if you need to save focus of button):
private void timer_Tick(object sender, EventArgs e)
{
justAnotherButton.Focus();
labelClock.Text = DateTime.Now.ToString();
}
You need to pass focus to another focusable control, it may be another Button, TextBox, etc. You may use button with zero Width and Height, so user won't see it.
If you are not concerned with keeping the same button focussed, set the focus to the parent form. Although this sounds like a bit of a nightmare to deal with, and i'd look for a way not not needing hundreds of buttons!
private void timer_Tick(object sender, EventArgs e)
{
formMain.Focus()
labelClock.Text = DateTime.Now.ToString();
}
You could create a container control that extends System.Windows.Forms.ContainerControl and override the ScrollToControl to return the current scroll position. Then add all your buttons to this control.
class MyContainer : ContainerControl
{
protected override System.Drawing.Point ScrollToControl(Control activeControl)
{
return base.AutoScrollPosition;
}
}
I'm wondering if it's possible to use ToolTip.SetToolTip or something similar to open a control as a tooltip instead of just a string (i.e. SetToolTip(controlToWhichToAdd, panelToDisplayAsToolTip) instead of passing a string as your second parameter).
If this isn't possible I'm guessing next best thing is displaying a panel on the mouse location on mouse_enter event on the control and removing it (or making it invisible) on mouse_leave.
Or are there other practices that make this possible in an easier way?
This is not possible out of the box. You have two choices. First option is to override the Draw Event, which will let you customize how the tooltip looks. Here is an example of this. Be sure you set the OwnerDraw property to true if you use this method!
Although the first method will work if you just need some simple customization, the second option will work best if you need more flexible options. The second option is to do what you already suggested and create your own sort of tooltip. Simply put, you would first create an event handler for the MouseEnter event. When that event fires, you'd enable a Timer. This timer would be the delay that occurs before the tooltip is show. Then finally, you'd just make your panel appear at the mouse coordinates.
Suppose you have a form with a button and timer on it and you want the button to have a tooltip that is a panel:
public partial class Form1 : Form
{
private Panel _myToolTipPanel;
private void Form1_Load(object sender, EventArgs e)
{
_myToolTipPanel = new Panel {Visible = false};
Controls.Add(_myToolTipPanel);
Label myLabel = new Label();
myLabel.Text = "Testing";
_myToolTipPanel.Controls.Add(myLabel);
}
private void button1_MouseEnter(object sender, EventArgs e)
{
timer1.Enabled = true;
}
private void button1_MouseLeave(object sender, EventArgs e)
{
timer1.Enabled = false;
_myToolTipPanel.Visible = false;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
Point position = Cursor.Position;
Point formPoisition = PointToClient(position);
_myToolTipPanel.Visible = true;
_myToolTipPanel.Location = formPoisition;
}
}
Now of course you will have to do some beautifying of the tooltip, but this is the general idea!
One Approach could be inheriting the ToolTip control and then override the SetToolTip and Show methods . Inside the SetToolTip the private method - SetToolTipInternal needs to be re-written , but most of the functionality could be reuse - it uses the Mouse Events ( leave , move) to bind region. but since tooltip uses internal's of windows to show the baloon window. you will have to override quite a bit of code.
but this could be time consuming and needs quite a bit of testing.
You could write a handler for the Tooltip.Popup event, and cancel the popup to display your own panel.
You'd need to clean it up at the appropriate time, though.
For example:
private void ToolTip1_Popup(Object sender, PopupEventArgs e)
{
e.Cancel = true;
//Do work here to display whatever control you'd like
}
If you're just looking for more formatting options in the tooltip display, an alternative is something like this CodeProject entry, which implements an HTML-enabled tooltip:
Have a simple form that has a PictureBox in one location. I want to change the cursor to the Cross cursor when entering that control, and change it back when it leaves.
private void Canvas_MouseEnter(object sender, EventArgs e)
{
this.Canvas.Cursor = Cursors.Cross;
}
private void Canvas_MouseLeave(object sender, EventArgs e)
{
this.Canvas.Cursor = Cursors.Default;
}
This doesn't work. If I look closely, I can see it quickly change on MouseEnter, but it flips right back to the default cursor. I have to add "this.Canvas.Cursor = Cursors.Cross;" to the MouseMove event in order for it to work, but then I can constantly see it flickering back to the default cursor.
What gives? This is the only cursor-related code in my whole application, what would be causing it to reset to the default cursor every time I move the mouse?
Thanks.
EDIT: I am an idiot. Person I am collaborating with on this little app had some cursor code tucked away somewhere else that was causing the problem. Thanks guys.
Why don't you set the cursor for the picturebox?
yourPictureBox.Cursor = Cursors.Cross;
I've tried in a new project from scratch (with just the mouseenter/leave handlers and nothing else) and it works.
Might be something else in your application ?
public Form1()
{
InitializeComponent();
pictureBox1.MouseHover += new EventHandler(PictureBox1_MouseHover);
}
void pictureBox1_MouseHover(object sender, EventArgs e)
{
this.PictureBox1.Cursor = Cursors.Cross;
}
You want to use MouseHover event handler.
I was building a simple form with one simple effect- opacity reduced when mouse is not over the form, and form becomes opaque when mouse is over it. I am currently encountering couple of difficulties:-
Firstly, I did this-
this.MouseHover += new EventHandler(Form1_MouseHover);
this.MouseLeave += new EventHandler(Form1_MouseLeave);
But I had 1 richtextbox in form too, and as mouse went over it, the form lost opacity again. I had to add this too:-
richTextBox1.MouseHover+=new EventHandler(Form1_MouseHover);
richTextBox1.MouseLeave+=new EventHandler(Form1_MouseLeave);
wondering if there was any better way,because there is still some gap between richtextbox and form boundaries, and form is losing opacity when mouse cursor goes there.
If the mouse is NOT over the form (suppose initially), the form is less opaque. Now, I want form to become opaque as soon as mouse goes over it, but it only happens when mouse movement over form stops completely. If I keep moving mouse over the form, it does not become opaque. Is this a problem with the way events are stored in message queue and all that or will I be able to do something, because I have seen applications with the effect I am trying to implement.
The MouseEnter/Leave events are too unreliable to do this. Best thing to do is just use a Timer that checks if the mouse is still inside the window. Drop a Timer on the form and make the code look like this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.Opacity = 0.99;
timer1.Interval = 200;
timer1.Enabled = true;
timer1.Tick += timer1_Tick;
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
timer1_Tick(this, e);
}
private void timer1_Tick(object sender, EventArgs e) {
this.Opacity = this.Bounds.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;
}
}
Btw: avoid increasing the Opacity to 1.0, that forces the native window to be recreated and that can have a lot of side-effects. Using 0.99 is best.
I might be wrong, but why would you use MouseHover event? MouseHover detects when the mouse stop moving on the form and is usually used to show Tooltips.
The event you are looking for is MouseEnter which is the opposite of MouseLeave and detects when the mouse enters the client rect of a window.
In the Leave event, just check if the cursor position is in the window client rect to know if it did actually leave the form or if it is just on top of child control.
Ofc if you use a region, you'll have to adapt the code.
private void Form1_MouseEnter(object sender, EventArgs e)
{
this.Opacity = 1;
}
private void Form1_MouseLeave(object sender, EventArgs e)
{
if (!this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)))
{
this.Opacity = 0.5;
}
}
Add a timer control then use below in timer's tick event. Above answers won't work if you have custom/user controls in your form. So have to use ClientRectangle
this.Opacity = this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;
private void Form1_MouseEnter(object sender, EventArgs e)
{
this.Opacity = 1.0;
}
private void Form1_MouseLeave(object sender, EventArgs e)
{
this.Opacity = 0.8;
}
How can I create and show a popup window at a specific time in WPF?
What I mean how to display the window on the side of system tray.
You could use a timer if you're trying to make the thing popup in a certain number of hours/seconds/minutes (or work out how many hours/seconds/minutes are left until your specific time comes around).
private System.Windows.Threading.DispatcherTimer popupTimer;
// Whatever is going to start the timer - I've used a click event
private void OnClick(object sender, RoutedEventArgs e)
{
popupTimer = new System.Windows.Threading.DispatcherTimer();
// Work out interval as time you want to popup - current time
popupTimer.Interval = specificTime - DateTime.Now;
popupTimer.IsEnabled = true;
popupTimer.Tick += new EventHandler(popupTimer_Tick);
}
void popupTimer_Tick(object sender, EventArgs e)
{
popupTimer.IsEnabled = false;
// Show popup
// ......
}
Ok, so you also want to know how to do a notifier popup type thing, which maybe this article in CodeProject might help.
Check out this question for firing an event at a set time.
You might want to check out DispatcherTimer.