I have a Winform, which is hidden initially on startup.
Thereafter the user is free to click the notification icon in the bottom and show it if they want, and when it is minimized it needs to go back into the system tray.
It starts in the tray fine - no problems. When you click to show it the first time though it appears, then for a fraction of a second looks like it is disappearing, then comes back. So it looks like it flickers a bit.
Then when you minimize it, it goes into the system tray as it should which is fine. When you click to show it again though (any time after you have done it once) it sort of glides in from either the system tray or the taskbar, I would prefer it to just appear, without the little animation.
public class Program : Form
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Program());
}
private NotifyIcon trayIcon;
private ContextMenu trayMenu;
public Program()
{
trayMenu = new ContextMenu();
trayMenu.MenuItems.Add("Exit", OnExit);
trayMenu.MenuItems.Add("Show", OnShow);
trayIcon = new NotifyIcon();
trayIcon.Text = "MyTrayApp";
trayIcon.Icon = new Icon(SystemIcons.Application, 40, 40);
trayIcon.ContextMenu = trayMenu;
trayIcon.Visible = true;
}
protected override void OnLoad(EventArgs e)
{
Visible = false;
ShowInTaskbar = false;
base.OnLoad(e);
}
protected override void OnResize(EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
Visible = false;
ShowInTaskbar = false;
}
base.OnResize(e);
}
private void OnExit(object sender, EventArgs e)
{
Application.Exit();
}
private void OnShow(object sender, EventArgs e)
{
Visible = true;
ShowInTaskbar = true;
TopMost = true;
WindowState = FormWindowState.Normal;
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
trayIcon.Dispose();
}
base.Dispose(isDisposing);
}
}
Any pointers on how to just get it to appear properly would be really appreciated.
Update
I have found the cause of the flickering, it happened when TopMost is set last, after is has been shown, so it redraws it on top, which makes sense.
So as it stands, it's just getting it to appear and disappear without the animations.
EDIT: You should only set the Visibility property in Onload(), just use Show() and Hide() to avoid the animations and be sure to change the WindowState accordingly.
I put your code into a regular Form (not in the Program.cs file) and deleted all superfluous code. This is what I ended up with and it doesn't show the "double" animation.
public partial class Form1 : Form
{
private NotifyIcon trayIcon;
private ContextMenu trayMenu;
public Form1()
{
InitializeComponent();
this.ClientSize = new System.Drawing.Size(284, 262);
this.Name = "Program";
trayMenu = new ContextMenu();
trayMenu.MenuItems.Add("Exit");
trayMenu.MenuItems.Add("Show", FormShow);
trayIcon = new NotifyIcon();
trayIcon.Text = "MyTrayApp";
trayIcon.Icon = new Icon(SystemIcons.Application, 40, 40);
trayIcon.ContextMenu = trayMenu;
trayIcon.Visible = true;
TopMost = true;
Resize += new EventHandler(Form1_Resize);
}
void Form1_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
ShowInTaskbar = false;
Hide();
trayIcon.Visible = true;
}
}
void FormShow(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
WindowState = FormWindowState.Normal;
}
ShowInTaskbar = true;
Show();
Focus();
trayIcon.Visible = false;
}
protected override void OnLoad(EventArgs e)
{
Visible = false;
ShowInTaskbar = false;
}
}
Related
I have a form. I want to make sure that the RegisterForm.cs form comes as childform when the toggle button I added on this form is activated. It works in a different position from the main panel when I call it normally. Whatever I've done, I haven't been able to solve this problem, can you help me with that?
FormMainMenu.cs
public void OpenChildForm(Form childForm)
{
if (currentChildForm != null)
{
//open only form
currentChildForm.Close();
}
currentChildForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
panelDesktop.Controls.Add(childForm);
panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();
lblTitleChildForm.Text = childForm.Text;
}
SozlesmeFormu.cs
public partial class SozlesmeFormu : Form
{
private bool toggleCheck = false;
public SozlesmeFormu()
{
InitializeComponent();
textBox1.Multiline = true;
textBox1.ScrollBars = ScrollBars.Both;
}
private void toggleSozlesme_CheckedChanged(object sender, EventArgs e)
{
toggleCheck = true;
toggleSozlesme.Enabled = false;
toggleSozlesme.OnBackColor = Color.DarkGray;
this.Close();
FormMainMenu formMain = new FormMainMenu();
formMain.OpenChildForm(new RegisterForm());
}
}
Whatever I did, I couldn't call RegisterForm as childform. It's always irrelevant from the main panel.
I have googled this and all the sites I have seen tell me the same thing for minimizing my app and then returning it to normal. I can minimize it fine but when I click on the icon in the tray then nothing happens. Here is my code.
private void Form1_SizeChanged(object sender, EventArgs e)
{
bool PointerNotOnTaskbar = Screen.GetWorkingArea(this).Contains(Cursor.Position);
if (this.WindowState == FormWindowState.Minimized && PointerNotOnTaskbar)
{
notifyIcon1.Icon = SystemIcons.Application;
this.ShowInTaskbar = false;
notifyIcon1.Visible = true;
}
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.ShowInTaskbar = true;
WindowState = FormWindowState.Normal;
notifyIcon1.Visible = false;
}
I have also tried
this.WindowState = FormWindowState.Normal;
Comment out this: this.ShowInTaskbar = false;
If the form is minimized and not visible in taskbar will take a spell to bring it back!
my request is suppose i have two sdi form. one sdi main form has button and when user click on that button then a overlay semi transparent window will appear and cover the main sdi form and as well as another sdi will come on top of the over lay window.
here is my overlay window code
namespace CSRAssistant
{
public partial class MaskedDialog : Form
{
static MaskedDialog mask;
static Form frmContainer;
private Form dialog;
private UserControl ucDialog;
private MaskedDialog(Form parent, Form dialog)
{
this.dialog = dialog;
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = System.Drawing.Color.Black;
this.Opacity = 0.50;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.Size = parent.ClientSize;
this.Location = parent.PointToScreen(System.Drawing.Point.Empty);
parent.Move += AdjustPosition;
parent.SizeChanged += AdjustPosition;
}
private MaskedDialog(Form parent, UserControl ucDialog)
{
this.ucDialog = ucDialog;
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = System.Drawing.Color.Black;
this.Opacity = 0.50;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.Size = parent.ClientSize;
this.Location = parent.PointToScreen(System.Drawing.Point.Empty);
parent.Move += AdjustPosition;
parent.SizeChanged += AdjustPosition;
}
private void AdjustPosition(object sender, EventArgs e)
{
Form parent = sender as Form;
this.Location = parent.PointToScreen(System.Drawing.Point.Empty);
this.ClientSize = parent.ClientSize;
}
//
public static DialogResult ShowDialog(Form parent, Form dialog)
{
mask = new MaskedDialog(parent, dialog);
dialog.StartPosition = FormStartPosition.CenterParent;
mask.MdiParent = parent.MdiParent;
mask.Show();
DialogResult result = dialog.ShowDialog(mask);
mask.Close();
return result;
}
public static DialogResult ShowDialog(Form parent, UserControl dialog)
{
mask = new MaskedDialog(parent, dialog);
frmContainer = new Form();
frmContainer.ShowInTaskbar = false;
frmContainer.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
frmContainer.StartPosition = FormStartPosition.CenterParent;
frmContainer.Height = dialog.Height;
frmContainer.Width = dialog.Width;
frmContainer.Controls.Add(dialog);
mask.MdiParent = parent.MdiParent;
mask.Show();
DialogResult result = frmContainer.ShowDialog(mask);
frmContainer.Close();
mask.Close();
return result;
}
public static void CloseDialog()
{
if (frmContainer != null)
{
frmContainer.Close();
}
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// MaskedDialog
//
this.ClientSize = new System.Drawing.Size(284, 262);
this.Name = "MaskedDialog";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MaskedDialog_FormClosing);
this.Load += new System.EventHandler(this.MaskedDialog_Load);
this.ResumeLayout(false);
}
private void MaskedDialog_Load(object sender, EventArgs e)
{
}
private void MaskedDialog_FormClosing(object sender, FormClosingEventArgs e)
{
}
}
}
this way i am calling my overlay when user click on main sdi button.
Form2 f2 = new Form2();
f2.Show();
MaskedDialog.ShowDialog(this, f2);
f2.Dispose();
f2 = null;
when i am running the code and MaskedDialog.ShowDialog(this, f2); is calling then i am getting a error....the error message is Form that is already visible cannot be displayed as a modal dialog box. Set the form's visible property to false before calling showDialog.
so i am not being able to understand where i am making the mistake. anyone can help me to fix the problem. thanks
You're doing this wrong - call mask.ShowDialog(), not mask.Show() and dialog.ShowDialog(). The error message is pretty clear - you can't ShowDialog a form that's already visible - and that's exactly what you're doing in dialog.ShowDialog(mask);.
Or, in a way that probably more closely shows what you want to do, when calling MaskedDialog.ShowDialog, do this:
Form2 f2 = new Form2();
MaskedDialog.ShowDialog(this, f2);
In other words - don't show the form you're going to ShowDialog. It's going to be made visible by the ShowDialog call.
This question already has answers here:
How to run an "empty" Windows Application that only has a NotifyIcon?
(3 answers)
Closed 6 years ago.
I added notifyIcon to the container and set Visible = true option, but no icon appeared.
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
this.SuspendLayout();
//
// notifyIcon1
//
this.notifyIcon1.Text = "Manager";
this.notifyIcon1.Visible = true;
//
// Form1
//
this.ClientSize = new System.Drawing.Size(0, 0);
this.ShowInTaskbar = false;
this.Visible = false;
}
I believe you need to add a few more events for this to work, Hope this helps
public Form2()
{
InitializeComponent();
notifyIcon1.Icon = SystemIcons.Asterisk;
notifyIcon1.DoubleClick += new EventHandler(notifyIcon1_DoubleClick);// to bring it back
this.Resize += new EventHandler(Form2_Resize);// to move it to tray
}
void notifyIcon1_DoubleClick(object sender, EventArgs e)
{
Show();
this.BringToFront();
this.WindowState = FormWindowState.Normal;
}
void Form2_Resize(object sender, EventArgs e)
{
if (this.WindowState ==FormWindowState.Minimized)
Hide();
}
notify Icon is shown when form is minimize. Try this
this.WindowState = FormWindowState.Minimized;
Is there any way to make the form semi-transparent while it is being moved and then become opaque when it's not being moved anymore? I have tried the Form_Move event with no luck.
I'm stuck, any help?
The reason the form loads as semi-transparent is because the form has to be moved into the starting position, which triggers the Move event. You can overcome that by basing whether the opacity is set, on whether the form has fully loaded.
The ResizeEnd event fires after a form has finished moving, so something like this should work:
bool canMove = false;
private void Form1_Load(object sender, EventArgs e)
{
canMove = true;
}
private void Form1_Move(object sender, EventArgs e)
{
if (canMove)
{
this.Opacity = 0.5;
}
}
private void Form1_ResizeEnd(object sender, EventArgs e)
{
this.Opacity = 1;
}
To do it properly I expect you'd need to override the message processing to respond to the title bar being held, etc. But you could cheat, and just use a timer so that you make it opaque for a little while when moved, so continuous movement works:
[STAThread]
static void Main()
{
using (Form form = new Form())
using (Timer tmr = new Timer())
{
tmr.Interval = 500;
bool first = true;
tmr.Tick += delegate
{
tmr.Stop();
form.Opacity = 1;
};
form.Move += delegate
{
if (first) { first = false; return; }
tmr.Stop();
tmr.Start();
form.Opacity = 0.3;
};
Application.Run(form);
}
}
Obviously you could tweak this to fade in/out, etc - this is just to show the overall concept.