C# - How to trigger opacity event when form loses focus? - c#

Purpose is to have the opacity event trigger when the form loses focus. The form has a setting for STAY ON TOP. The visual effect would be to click on a possibly overlapping window, and yet the form when not focused on would stay on top, but in the corner slightly transparent, keeping it within easy access, but providing visibility to the stuff underneath.
I 've googled and googled, and can't figure out how to get this event to properly fire when form loses focus, and then when form gains focus back to restore opacity to 100% or the level determined elsewhere.
Tips?
// under designer.cs
//
// CollectionToolForm
//
//other code....
this.LostFocus += new System.EventHandler(goTransparent);
//method
private void goTransparent(object sender, EventArgs e)
{
if (transparentCheck.Checked == true)
{
this.Opacity = 0.50;
}
else
{
this.Opacity = 1;
}
}

It sounds as if you are looking for the Activated and Deactivate events.
Update
In response to the comment about LostFocus event, it could be of interest to clarify how it works. The LostFocus event of the Form is inherited from Control. It is raised when a controls loses focus; either because the form as such is being deactivated (focus moves to another application for instance), or because focus moves to another control within the same form.
If you hook up an event handler for the LostFocus event of a form that contains only at least one control that can receive focus, you will find that the LostFocus event of the form is raised immediately after the form is displayed. This is because focus moves from the form (which is a Control) to the first focusable control on the form.
So, the form being active and the form being focused are two separate behaviours.

You tried doing it with mouse enter/leave events?
public Form1()
{
this.MouseEnter += new System.EventHandler(this.Form1_MouseEnter);
this.MouseLeave += new System.EventHandler(this.Form1_MouseLeave);
}
private void Form1_MouseLeave(object sender, EventArgs e)
{
this.Opacity = 0.5;
}
private void Form1_MouseEnter(object sender, EventArgs e)
{
this.Opacity = 1;
}

Related

C# LocationChanged event not firing

I have a form that I use to overlay things that I don't want the user to mess with at a given time. When I use this overlay form to cover an entire form, everything works beautifully. However, when I use it to cover a panel, the LocationChanged event never fires! I tried changing the panel's properties to see if something was preventing it somehow. I tried using Dock = Fill, I have also tried matching the size of its parent control and using anchors... All to no avail.
Is there something I am missing that would prevent the LocationChanged event from firing?
Overlay form:
Panel PanelToCover = new Panel();
public Overlay(Panel paneltocover)
{
PanelToCover = paneltocover;
this.StartPosition = FormStartPosition.Manual;
this.AutoScaleMode = AutoScaleMode.None;
this.Location = paneltocover.PointToScreen(Point.Empty);
this.ClientSize = paneltocover.ClientSize;
paneltocover.LocationChanged += PanelCover_LocationChanged;
paneltocover.ClientSizeChanged += PanelCover_ClientSizeChanged;
this.Show(paneltocover);
paneltocover.Focus();
}
private void PanelCover_LocationChanged(object sender, EventArgs e)
{
this.Location = PanelToCover.PointToScreen(Point.Empty);
}
private void PanelCover_ClientSizeChanged(object sender, EventArgs e)
{
// This works without an issue
this.ClientSize = PanelToCover.ClientSize;
}
Edit:
I am silly. The panel's location will never change in respect to its owner. I was checking the PointToScreen value, watching it change, and wondering why the LocationChanged event never fired.
The location of the panel is relative to the form, so if you're moving the form the location_changed event won't be triggered on the panel. That's why the event is not triggered.
The panel's Location property represents the location of the panel on its containing control (the form). The panel is not moving with respect to the form, so LocationChanged never fires.

I have a user control on my Form1 but when i add a mouse event of the control it dosen't do anything why?

private void lineGraph1_MouseEnter(object sender, EventArgs e)
{
MessageBox.Show("test");
}
I want that when I move the mouse over/on the control area it will show the message.
I downloaded the control dll from here :
http://www.codeproject.com/Articles/274318/Line-Graph-Component-in-Csharp
Downloaded the demo and used the dll file there.
So I have now the control on Form1 and then I did on the control in the Form1 designer right click mouse properties events and double click on Mouse Enter but nothing when im moving the mouse over the control nothing happen.
What did I do wrong ?
Adding the method does nothing by itself. You have to add it as an event handler, such as with
lineGraph1.MouseEnter += new EventHandler(lineGraph1_MouseEnter);
The Form Editor does this for you when you select the MouseEnter event from the events dropdown at top right.
I think it's due to the fact LineGraph has some controls over itself.
For example, if you put your onmouseenter event on the PlotArea control directly it will probably work fine.
public PlotArea()
{
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.MouseEnter += new EventHandler(PlotArea_MouseEnter);
}
void PlotArea_MouseEnter(object sender, EventArgs e)
{
MessageBox.Show("test");
}

How to determine which form was brought to front by clicking it?

I have an application with a Panel containing children Form objects. When I click one of the children Form it brings to front. I would like to know which one is in front now...
I've looked in event list but cant find proper event form my purpose :(
These methods doesn't work:
protected void OpenedFileForm_Enter(object sender, EventArgs e)
{
MessageBox.Show("enter");
}
protected void OpenedFileForm_Click(object sender, EventArgs e)
{
MessageBox.Show("click");
}
protected void OpenedFileForm_Activated(object sender, EventArgs e)
{
MessageBox.Show("activated");
}
protected void OpenedFileForm_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("mouse click");
}
protected void OpenedFileForm_Shown(object sender, EventArgs e)
{
MessageBox.Show("shown");
}
OpenFileDialog openFile1 = new OpenFileDialog();
openFile1.DefaultExt = "*.txt";
openFile1.Filter = "TXT Files|*.txt|RTF Files|*.rtf";
if (openFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
openFile1.FileName.Length > 0)
{
switch (Path.GetExtension(openFile1.FileName))
{
case ".txt":
txtForm childTXT = new txtForm();
this.childForms.Add(childTXT);
childTXT.Parent = this.mainPanel;
childTXT.richTextBox1.LoadFile(openFile1.FileName, RichTextBoxStreamType.PlainText);
childTXT.Show();
break;
}
}
Have you tried the Form.Activated Event?
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.activated(v=vs.80).aspx
Edit:
If you are in an MDI application, you might need to use MdiChildActivate instead.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.mdichildactivate.aspx
This code can only work when you set the Form.TopLevel property to false. Which makes it turn into a child control, almost indistinguishable from a UserControl.
This has many side-effects, for one there is no notion of "front" anymore. The Z-order of child controls is determined by their position in their parent's Controls collection. And it affects the events it fires, Activated and Deactivated will never fire. Furthermore, the Form class was designed to be a container control, it doesn't like taking the focus itself. Its child controls get the focus, the Form class doesn't have any use for focus. Which is why the Enter, Click and MouseClick events don't fire, they are events that require focus.
Long story short, what you are trying to do doesn't make a wholeheckofalot of sense. If it is strictly the Z-order you want to fix then write an event handler for the MouseDown event:
void OpenedFileForm_MouseDown(object sender, MouseEventArgs e) {
var frm = (Form)sender;
frm.BringToFront();
}
You could add frm.Select() to get the Enter event to fire, but only do that if the form doesn't contain any focusable controls itself. Do note that there is evidence that you don't assign the events correctly in your code. The Shown event does fire. It is also important that you set the FormBorderStyle to None, the title bar cannot indicate activation status anymore.
Ok, I got this! Thx for help everyone. You gave me a hint to think about equity of my strange MDI idea where Panel is parent for other Forms. I Removed SplitContainer containing Panel and just did standard MDI application, where Forms are MDIChildren of main Form.
childTXT.MdiParent = this;

MouseHover and MouseLeave Events controlling

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;
}

MouseWheel event doesn't fire when using any control with scrolbars (in C# Windows Forms)

MouseWheel event doesn't fire
when I' am using any control (ListBox, Panel, TextBox) with scrollbars.
To reproduce problem:
public class Form1 : Form
{
private readonly Button button1;
private readonly TextBox textBox1;
private void button1_MouseWheel(object sender, MouseEventArgs e)
{
ToString(); // doesn't fire when uncomment lines below
}
public Form1()
{
button1 = new Button();
textBox1 = new TextBox();
SuspendLayout();
button1.Location = new System.Drawing.Point(80, 105);
button1.Size = new System.Drawing.Size(75, 23);
button1.MouseWheel += button1_MouseWheel;
button1.Click += button1_Click;
textBox1.Location = new System.Drawing.Point(338, 105);
//textBox1.Multiline = true; // uncomment this
//textBox1.ScrollBars = ScrollBars.Vertical; // uncomment this
textBox1.Size = new System.Drawing.Size(100, 92);
ClientSize = new System.Drawing.Size(604, 257);
Controls.Add(textBox1);
Controls.Add(button1);
ResumeLayout(false);
PerformLayout();
}
// Clicking the button sets Focus, but even I do it explicit Focus() or Select()
// still doesn't work
private void button1_Click(object sender, System.EventArgs e)
{
button1.Focus();
button1.Select();
}
}
I was having the same problem, and what worked for me was to add a handler for the event MouseEnter in the control, that one is triggered with or without focus.
private void chart1_MouseEnter(object sender, EventArgs e)
{
chart1.Focus();
}
After that I could get the mouseWheel events with no problems.
You normally need to make sure the control you want to handle the MouseWheel event is active.
For example try calling button1.Select() in the Form Load (or Shown) event and then using the scroll wheel.
eg:
private void Form1_Load(object sender, EventArgs e)
{
button1.MouseWheel += new MouseEventHandler(button1_MouseWheel);
button1.Select();
}
I found solution, gility is default "Mouse Configuration". Lenovo USB Optical Wheel Mouse default configuration is:
Control Panel/Mouse/Wheel/Whell->Enable Universal Scrolling;
I changed to:
Control Panel/Mouse/Wheel/Whell->Use Microsoft Office 97 Scrolling Emulation Only
Now in .net code MouseWheel working with Focused Control.
But questions are:
how can I fix it in .net code?
how can I detect this situation in .net code?
Any ideas ?
I tried your example, and, whether the lines were commented or not, the MouseWheel event only fires if the button is focused. This behavior is by design. (the MouseWheel event, like keyboard events, goes to the focused control)

Categories

Resources