I have a C# Winform project and I need to create a very simple linear workflow just to show visually what is the current status of the record.
Here is a sample image of what I want to do:
I will have to be able to draw the border on the item that is the actual status.
Any advice?
If you don't want to have to actually draw on it, you can do as rashfmnb suggested. Here is an example.
The setup:
Form = MainForm
Panel = pnlOuter [Padding = 5]
Panel = pnlInner [Parent = pnlOuter, done by placing it inside the other one; Dock = Fill]
Button = ToggleColor (to trigger the click event handler below)
The code:
public partial class MainForm : Form
{
bool isOn = false;
public MainForm()
{
InitializeComponent();
pnlInner.BackColor = Color.LightGoldenrodYellow;
pnlOuter.BackColor = Color.LightGoldenrodYellow;
}
private void ToggleColor_Click(object sender, EventArgs e)
{
if (isOn)
{
pnlOuter.BackColor = Color.LightGoldenrodYellow;
isOn = false;
}
else
{
pnlOuter.BackColor = Color.Red;
isOn = true;
}
}
}
This simple example just toggles the background of the outer panel. In your case, you would use different values to check what should be set and so forth.
Alright, this is a little strange, but essentially I needed a message box class with buttons that did not come as options within the message box class in c#. Therefore, I read up on how to create my own class (here is the link if your interested: http://social.msdn.microsoft.com/Forums/vstudio/en-US/1086b27f-683c-457a-b00e-b80b48d69ef5/custom-buttons-in-messagebox?forum=csharpgeneral), and used an example provided inside of that. Here is the relevant code:
public partial class Form1 : Form
{
public static bool MessageSucceded { get; set; }
public static string MessageContent{ private get; set; }
private void buttonMyMessageBox_Click(object sender, EventArgs e)
{
using (MyMessageForm myForm = new MyMessageForm())
{
myForm.ShowDialog();
if (MessageSucceded = myForm.ShowDialog(this) == DialogResult.OK)
{
if (MessageContent== "Yes do it")
{
//HERE DO WHAT YOU WANT IF THE USER CLICKS ON BUTTON YES DO IT
}
else if (MessageContent== "No, don`t do it")
{
//HERE DO WHAT YOU WANT IF THE USER CLICKS ON BUTTON NO, DON`T DO IT
}
}
}
}
}
public partial class MyMessageForm : Form
{
private void MyMessageForm_Load(object sender, EventArgs e)
{
this.StartPosition = FormStartPosition.CenterScreen;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.MinimizeBox = false;
this.MaximizeBox = false;
this.buttonYes.Text = "Yes do it";
this.buttonNo.Text = "No, don`t do it";
this.labelMyForm.Text = "Are you sure you want to… ?";
}
private void buttonYes_Click(object sender, EventArgs e)
{
Form1.MessageSucceded = true;
Form1.MessageContent= buttonYes.Text;
this.DialogResult = DialogResult.OK;
this.Close();
}
private void buttonNo_Click(object sender, EventArgs e)
{
Form1.MessageSucceded = true;
Form1.MessageContent= buttonNo.Text;
this.DialogResult = DialogResult.OK;
this.Close();
}
}
This works exactly as I intended it to, except for one small detail. Just before the message box pops up, for a split second, a terminal version of the message box form opens up, before it closes on its own and the windows form version opens and functions as expected. I can't understand why this is happening, and it isn't causing any performance issues that I can notice, but aesthetically it looks very bad. Does anyone know why this is happening or how to stop it? I'm using Visual Studio 2010 Express for what its worth. Thanks for any help you have and taking the time to read this.
Edit: heres my code for main:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
You're invoking ShowDialog() twice:
myForm.ShowDialog();
if (MessageSucceded = myForm.ShowDialog(this) == DialogResult.OK) {
Form has been closed so it'll close immediatly, right way to do it is to save its first result and check that in your if condition:
var result = myForm.ShowDialog();
if (MessageSucceded = (result == DialogResult.OK)) {
Or directly:
MessageSucceded = myForm.ShowDialog() == DialogResult.OK;
if (MessageSucceded) {
Moreover if you returns different results according to clicked button then you do not need to compare MessageContent (it's also a bad idea to have a reference to caller just to return a result):
private void buttonYes_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Yes;
this.Close();
}
private void buttonNo_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.No;
this.Close();
}
Note that now you can simply remove such code and add proper DialogResult property to each button (because assign Form.DialogResult and call Form.Close() is default behavior if Button.DialogResult property is assigned). Done that you can simply use it like this:
switch (myForm.ShowDialog())
{
case DialogResult.Yes:
break;
case DialogResult.No:
case DialogResult.Cancel: // Unless ControlBox is also Hidden
break;
}
As last note: if you're targeting Vista+ you may also check Task Dialog instead of writing a custom form (you may keep it as fallback for XP's users).
I was wondering how I would make an image appear inside a messagebox that I set up so that whenever the mouse enters a label, it displays the messagebox. What would the code be for the image insertion?
Quick and dirty way to achieve this is to create another windows form that will have same buttons as message box but that will also have an image.
Create public Boolean property in this form that will be named something like OKButtonClicked that will tell you whether OK or Cancel was clicked
Set ControlBox property to False so that minimize, maximize and close buttons are not shown
Here is a code behind for this form
public partial class MazeForm : Form
{
public MazeForm()
{
InitializeComponent();
}
private bool okButton = false;
public bool OKButtonClicked
{
get { return okButton; }
}
private void btnOK_Click(object sender, EventArgs e)
{
okButton = true;
this.Close();
}
private void btnCancel_Click(object sender, EventArgs e)
{
okButton = false;
this.Close();
}
}
Finally in your main form you can do something like this
MazeForm m = new MazeForm();
m.ShowDialog();
bool okButtonClicked = m.OKButtonClicked;
Note that this is something I quickly created in 15 min and that it probably needs more work but it will get you in the right direction.
I would like to achieve the same effect like in this article but for windows forms, is it even possible without hosting the control on different Form?
EDIT
I'm more interested in implementing the exact behavior of the control in the article, showing the control on the form and blocking the calling function, but without using other form for this purpose.
You can create a UserControl with the two buttons and the label for the message, then set its visibility to false in the constructor:
public MyDialog()
{
InitializeComponent();
Visible = false;
}
Then you add three variables to the control:
Form _parent;
bool _result;
bool _clicked = false;
the parent Form will be the Form your control is contained in and must be set before using the control, since it has to know what has to be disabled.
public void SetParent(Form f)
{
_parent = f;
}
_result will contain the result of the dialog, and _clicked will be used to determine when to close your dialog. What has to be done when you show your dialog is:
set the label
disable the form (but not the dialog)
make the dialog visible
wait for the user to click one of the buttons
hide the dialog
reenable the parent form
return the result
So you could add this method to enable/disable the parent form:
private void ParentEnabled(bool aBool)
{
if (_parent == null)
return;
foreach (Control c in _parent.Controls)
if (c != this)
c.Enabled = aBool;
}
and use it in the ShowDialog method:
public bool ShowDialog(string msg)
{
if (_parent == null)
return false;
// set the label
msgLbl.Text = msg;
// disable the form
ParentEnabled(false);
// make the dialog visible
Visible = true;
// wait for the user to click a button
_clicked = false;
while (!_clicked)
{
Thread.Sleep(20);
Application.DoEvents();
}
// reenable the form
ParentEnabled(true);
// hide the dialog
Visible = false;
// return the result
return _result;
}
Obviously the buttons have the responsibility to set the _result and _clicked variables:
private void okBtn_Click(object sender, EventArgs e)
{
_result = true;
_clicked = true;
}
private void cancelBtn_Click(object sender, EventArgs e)
{
_result = false;
_clicked = true;
}
How about creating transparent form that in the middle contains text on opaque shape (whatever you like). Then at runtime you would resize this form to have same size as the window over which you want to display it and place it so that it covers it.
I have an application with one form in it, and on the Load method I need to hide the form.
The form will display itself when it has a need to (think along the lines of a outlook 2003 style popup), but I can' figure out how to hide the form on load without something messy.
Any suggestions?
I'm coming at this from C#, but should be very similar in vb.net.
In your main program file, in the Main method, you will have something like:
Application.Run(new MainForm());
This creates a new main form and limits the lifetime of the application to the lifetime of the main form.
However, if you remove the parameter to Application.Run(), then the application will be started with no form shown and you will be free to show and hide forms as much as you like.
Rather than hiding the form in the Load method, initialize the form before calling Application.Run(). I'm assuming the form will have a NotifyIcon on it to display an icon in the task bar - this can be displayed even if the form itself is not yet visible. Calling Form.Show() or Form.Hide() from handlers of NotifyIcon events will show and hide the form respectively.
Usually you would only be doing this when you are using a tray icon or some other method to display the form later, but it will work nicely even if you never display your main form.
Create a bool in your Form class that is defaulted to false:
private bool allowshowdisplay = false;
Then override the SetVisibleCore method
protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(allowshowdisplay ? value : allowshowdisplay);
}
Because Application.Run() sets the forms .Visible = true after it loads the form this will intercept that and set it to false. In the above case, it will always set it to false until you enable it by setting allowshowdisplay to true.
Now that will keep the form from displaying on startup, now you need to re-enable the SetVisibleCore to function properly by setting the allowshowdisplay = true. You will want to do this on whatever user interface function that displays the form. In my example it is the left click event in my notiyicon object:
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
this.allowshowdisplay = true;
this.Visible = !this.Visible;
}
}
I use this:
private void MainForm_Load(object sender, EventArgs e)
{
if (Settings.Instance.HideAtStartup)
{
BeginInvoke(new MethodInvoker(delegate
{
Hide();
}));
}
}
Obviously you have to change the if condition with yours.
protected override void OnLoad(EventArgs e)
{
Visible = false; // Hide form window.
ShowInTaskbar = false; // Remove from taskbar.
Opacity = 0;
base.OnLoad(e);
}
At form construction time (Designer, program Main, or Form constructor, depending on your goals),
this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;
When you need to show the form, presumably on event from your NotifyIcon, reverse as necessary,
if (!this.ShowInTaskbar)
this.ShowInTaskbar = true;
if (this.WindowState == FormWindowState.Minimized)
this.WindowState = FormWindowState.Normal;
Successive show/hide events can more simply use the Form's Visible property or Show/Hide methods.
Try to hide the app from the task bar as well.
To do that please use this code.
protected override void OnLoad(EventArgs e)
{
Visible = false; // Hide form window.
ShowInTaskbar = false; // Remove from taskbar.
Opacity = 0;
base.OnLoad(e);
}
Thanks.
Ruhul
Extend your main form with this one:
using System.Windows.Forms;
namespace HideWindows
{
public class HideForm : Form
{
public HideForm()
{
Opacity = 0;
ShowInTaskbar = false;
}
public new void Show()
{
Opacity = 100;
ShowInTaskbar = true;
Show(this);
}
}
}
For example:
namespace HideWindows
{
public partial class Form1 : HideForm
{
public Form1()
{
InitializeComponent();
}
}
}
More info in this article (spanish):
http://codelogik.net/2008/12/30/primer-form-oculto/
I have struggled with this issue a lot and the solution is much simpler than i though.
I first tried all the suggestions here but then i was not satisfied with the result and investigated it a little more.
I found that if I add the:
this.visible=false;
/* to the InitializeComponent() code just before the */
this.Load += new System.EventHandler(this.DebugOnOff_Load);
It is working just fine.
but I wanted a more simple solution and it turn out that if you add the:
this.visible=false;
/* to the start of the load event, you get a
simple perfect working solution :) */
private void
DebugOnOff_Load(object sender, EventArgs e)
{
this.Visible = false;
}
You're going to want to set the window state to minimized, and show in taskbar to false. Then at the end of your forms Load set window state to maximized and show in taskbar to true
public frmMain()
{
Program.MainForm = this;
InitializeComponent();
this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;
}
private void frmMain_Load(object sender, EventArgs e)
{
//Do heavy things here
//At the end do this
this.WindowState = FormWindowState.Maximized;
this.ShowInTaskbar = true;
}
Put this in your Program.cs:
FormName FormName = new FormName ();
FormName.ShowInTaskbar = false;
FormName.Opacity = 0;
FormName.Show();
FormName.Hide();
Use this when you want to display the form:
var principalForm = Application.OpenForms.OfType<FormName>().Single();
principalForm.ShowInTaskbar = true;
principalForm.Opacity = 100;
principalForm.Show();
This works perfectly for me:
[STAThread]
static void Main()
{
try
{
frmBase frm = new frmBase();
Application.Run();
}
When I launch the project, everything was hidden including in the taskbar unless I need to show it..
Override OnVisibleChanged in Form
protected override void OnVisibleChanged(EventArgs e)
{
this.Visible = false;
base.OnVisibleChanged(e);
}
You can add trigger if you may need to show it at some point
public partial class MainForm : Form
{
public bool hideForm = true;
...
public MainForm (bool hideForm)
{
this.hideForm = hideForm;
InitializeComponent();
}
...
protected override void OnVisibleChanged(EventArgs e)
{
if (this.hideForm)
this.Visible = false;
base.OnVisibleChanged(e);
}
...
}
Launching an app without a form means you're going to have to manage the application startup/shutdown yourself.
Starting the form off invisible is a better option.
This example supports total invisibility as well as only NotifyIcon in the System tray and no clicks and much more.
More here: http://code.msdn.microsoft.com/TheNotifyIconExample
As a complement to Groky's response (which is actually the best response by far in my perspective) we could also mention the ApplicationContext class, which allows also (as it's shown in the article's sample) the ability to open two (or even more) Forms on application startup, and control the application lifetime with all of them.
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainUIForm mainUiForm = new MainUIForm();
mainUiForm.Visible = false;
Application.Run();
}
I had an issue similar to the poster's where the code to hide the form in the form_Load event was firing before the form was completely done loading, making the Hide() method fail (not crashing, just wasn't working as expected).
The other answers are great and work but I've found that in general, the form_Load event often has such issues and what you want to put in there can easily go in the constructor or the form_Shown event.
Anyways, when I moved that same code that checks some things then hides the form when its not needed (a login form when single sign on fails), its worked as expected.
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 form1 = new Form1();
form1.Visible = false;
Application.Run();
}
private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
Application.Exit();
}
Here is a simple approach:
It's in C# (I don't have VB compiler at the moment)
public Form1()
{
InitializeComponent();
Hide(); // Also Visible = false can be used
}
private void Form1_Load(object sender, EventArgs e)
{
Thread.Sleep(10000);
Show(); // Or visible = true;
}
In the designer, set the form's Visible property to false. Then avoid calling Show() until you need it.
A better paradigm is to not create an instance of the form until you need it.
Based on various suggestions, all I had to do was this:
To hide the form:
Me.Opacity = 0
Me.ShowInTaskbar = false
To show the form:
Me.Opacity = 100
Me.ShowInTaskbar = true
Why do it like that at all?
Why not just start like a console app and show the form when necessary? There's nothing but a few references separating a console app from a forms app.
No need in being greedy and taking the memory needed for the form when you may not even need it.
I do it like this - from my point of view the easiest way:
set the form's 'StartPosition' to 'Manual', and add this to the form's designer:
Private Sub InitializeComponent()
.
.
.
Me.Location=New Point(-2000,-2000)
.
.
.
End Sub
Make sure that the location is set to something beyond or below the screen's dimensions. Later, when you want to show the form, set the Location to something within the screen's dimensions.