How I can add a Splash Screen in C#? - c#

In VB.NET there is an option to add a Splash Screen when you click Add New Window but when I do that with C#, I can't find any thing.
so
How I can add a Splash Screen in C#?

(I'm on my Mac now so I may be a bit rusty...)
You need to open up your project preferences.
Project -> Preferences
In the first tab, select there is a dropdown menu called "Startup Object". The default is Form1.csYou should be able to change that to a splash screen window.

In Visual Studio 2010, this is really easy. Simply add an image to your Solution, then right-click on the image, and set it's Build Action to "SplashScreen".
No coding required!

Add a reference to Microsoft.VisualBasic. Then write the following code in Program.cs
static class Program
{
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
new MyApp().Run(args);
}
public class MyApp : WindowsFormsApplicationBase
{
protected override void OnCreateSplashScreen()
{
this.SplashScreen = new MySplashScreen();
}
protected override void OnCreateMainForm()
{
// Do stuff that requires time
System.Threading.Thread.Sleep(5000);
// Create the main form and the splash screen
// will automatically close at the end of the method
this.MainForm = new MyMainForm();
}
}
}

Related

C# form switch and vice versa

Assume that I have a C# Solution with 3 projects Main, Program1, Program2.
I want to have a "Main form", when I click on button "Program1" the main form will be hidden, Program1 will be showed, and when I close Program1, the Main form will return.
How can I do this?
I tried add Program1 and PRogram2 as Reference to Project Main and code like below in Main, it works for call Program1, but can't handle event Program1.closed() because when I try to reference Main to Program1, it error
---------------------------
Microsoft Visual Studio
---------------------------
A reference to 'Main' could not be added. Adding this project as a reference would cause a circular dependency.
---------------------------
OK
---------------------------
I searched Google and got nothing helpful!
using System;
using System.Windows.Forms;
namespace Switch
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Program1.Form1 pf1 = new Program1.Form1();
pf1.Show();
this.Hide();
}
}
}
As zcui93 commented you can use process to make it work. You can either have all 3 in same folder (when you deploy the app on client machine)
using System.Diagnostics;
...
Process process = new Process();
// Configure the process using the StartInfo properties.
process.StartInfo.FileName = "process.exe";
process.StartInfo.Arguments = "-n";
process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
process.Start();
process.WaitForExit();// Waits here for the process to exit.
In C# you can use the Process.Exited event. This event doesn't work when someone close the app when someone kill the app from task manager.
Circular dependencies use to happen when the project arquitecture is not good.
In your case i think the problem migth be the program1 or program2 have Main as a reference.
Remove de Main reference from the program1 and program2.
The main project must have reference to the program1 and program2.
Thanks everyone for answers!
After confirmed with customer, they don't strictly need the "mainform" to be hidden, so I came with another easier solution:
1. For the "child form", I use ShowDiaglog() instead of Show()
private void btnChildForm1_Click(object sender, EventArgs e)
{
var frm = new ChildForm1();
frm.ShowDialog();
}
For the mainform, I use mutex to force it to be only 1 instance:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
[STAThread]
static void Main()
{
var mutex = new Mutex(true, "MainForm", out var result);
if (!result)
{
MessageBox.Show("Running!");
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
GC.KeepAlive(mutex);
}
}

How can I animate a progress indicator in a splash screen of a windows application

I have created a splash screen in my windows application. I want a cycling "ring" progress indicator (like the one shown on the Windows 8 boot screen) to be added on splash screen until the main form is connected. The code in program.cs is:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
logo f = new logo();
f.Shown += new EventHandler((o, e) =>
{
System.Threading.Thread t = new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(4000);
f.Invoke(new Action(() => { f.Close(); }));
});
t.IsBackground = true;
t.Start();
});
}
logo is the start up form or splash screen I want to add progress bar or ring progress indicator to as in windows 8 startup.
There isn't a specific "cycle" progress ring control within the default control set, so I'd say you have two options:
Add a standard horizontal ProgressBar, and set its style to Marquee - this will give you the indeterminate "progress is happening but we're not sure when it's going to finish" look:
myProgressBar.Style = ProgressBarStyle.Marquee;
If you want a ring/circular progress indicator, then you're better off using an animated .gif or similar and the ImageAnimator control.
There is a good example of loading a gif and stepping through the frames on MSDN on the documentation for the ImageAnimator.Animate method:
Create a control, such as "AnimatedProgress":
public partial class AnimatedProgress : UserControl
{
//Create a Bitmpap Object.
Bitmap animatedImage = new Bitmap("circle_progress_animation.gif");
bool currentlyAnimating = false;
//This method begins the animation.
public void AnimateImage()
{
if (!currentlyAnimating)
{
//Begin the animation only once.
ImageAnimator.Animate(animatedImage, new EventHandler(this.OnFrameChanged));
currentlyAnimating = true;
}
}
private void OnFrameChanged(object o, EventArgs e)
{
//Force a call to the Paint event handler.
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
//Begin the animation.
AnimateImage();
//Get the next frame ready for rendering.
ImageAnimator.UpdateFrames();
//Draw the next frame in the animation.
e.Graphics.DrawImage(this.animatedImage, new Point(0, 0));
}
}
Add this control to your logo form:
public Logo()
{
InitializeComponent();
var progressSwirl = new AnimatedProgress();
progressSwirl.Location = new Point(50, 50);
Controls.Add(progressSwirl);
}
(I found adding it via code worked better than using the designer as I'd just referenced the image fairly crudely in my AnimatedProgress control and the VS designer couldn't find the image.)
Your cycling ring will then appear on your splash screen.
In terms of the "simplest" way to show the splash screen props must go to Veldmius for pointing out the SpalshScreen property:
Start by adding a reference to Microsoft.VisualBasic.dll to your project, then update your program.cs to something like:
using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;
namespace WindowsFormsApplication1
{
public class Startup : WindowsFormsApplicationBase
{
protected override void OnCreateSplashScreen()
{
SplashScreen = new logo();
}
protected override void OnCreateMainForm()
{
MainForm = new Form1();
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
new Startup().Run(new string[]{});
}
}
}
To test this, I added a Thread.Sleep(5000) to the loading event of my main form, and there you have it - my logo page displayed with an animated progress for 5 seconds then my main form loaded in.

Create a C# component for a SplashScreen

I want create a new component which shows a splash screen when i call the .show() method. The component must be like a Windows Form with an image and a duration in msec passed like parameters. What type of project should I choose in Visual Studio for do that? If I choose a ClassLibrary, it create a dll Class but if I choose a new ControlLibrary it create a new control, but I can't use a Windows Form.
protected int nSec;
public SplashScreen(string img, int nSec)
{
// duration
this.nSec = nSec;
// background splash screen
this.BackgroundImage = Image.FromFile("img.jpg");
InitializeComponent();
}
private void SplashScreen_Load(object sender, EventArgs e)
{
timer1.Interval = nSec * 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
this.Close()
}
I want reuse this "component" in other future work without create a new one every time.
Avoid assuming there's magic behind these project templates, you can easily configure the project yourself. Using the Class Library project template is fine, just right-click the project after you created it, pick Add New Item and select "Windows Form". Other than adding the form and opening it in the designer, that also added two items to your project's References node: System.Drawing and System.Windows.Forms
Which you automatically get when you pick the "Windows Forms Control Library" project template. Which also automatically added a UserControl. Which you don't need, just right-click the UserControl1.cs item in the project and pick Delete. Add New Item to select "Windows Form", just as above. Two ways to get the same result.
Sounds like they want you to make a class library and have it create the form for you.
//Whatever other usings you want
using System.Windows.Forms; //Include the win forms namespace so you create the form
namespace ClassLibrary1
{
public static class Class1
{
public static Form CreateNewForm()
{
var form1 = new Form();
form1.Width = 200;
form1.Height = 200;
form1.Visible = true;
form1.Activate(); //Unsure if you need to call Activate...
//You're going to want to modify all the values you want the splash screen to have here
return form1;
}
}
}
So in another project, say a console app, I can just reference the class library I just made, call the CreateForm function and it's gonna make a form at runtime pop up with a width and height of 200.
using ClassLibrary1; //You'll need to reference this
//Standard console app template
static void Main(string[] args)
{
var x = Class1.CreateNewForm(); //Bam form pops up, now just make it a splash screen.
Console.ReadLine();
}
Hope that's what you were looking for

WindowsFormsApplicationBase SplashScreen makes login form ignore keypresses until I click on it - how to debug?

My WinForms app has a simple modal login form, invoked at startup via ShowDialog(). When I run from inside Visual Studio, everything works fine. I can just type in my User ID, hit the Enter key, and get logged in.
But when I run a release build directly, everything looks normal (the login form is active, there's a blinking cursor in the User ID MaskedEditBox), but all keypresses are ignored until I click somewhere on the login form. Very annoying if you are used to doing everything from the keyboard.
I've tried to trace through the event handlers, and to set the focus directly with code, to no avail.
Any suggestions how to debug this (outside of Visual Studio), or failing that - a possible workaround?
Edit
Here's the calling code, in my Main Form:
private void OfeMainForm_Shown(object sender, EventArgs e)
{
OperatorLogon();
}
private void OperatorLogon()
{
// Modal dialogs should be in a "using" block for proper disposal
using (var logonForm = new C21CfrLogOnForm())
{
var dr = logonForm.ShowDialog(this);
if (dr == DialogResult.OK)
SaveOperatorId(logonForm.OperatorId);
else
Application.Exit();
}
}
Edit 2
Didn't think this was relevant, but I'm using Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase for it's splash screen and SingleInstanceController support.
I just commented out the splash screen code, and the problem has disappeared. So that's opened up a whole new line of inquiry...
Edit 3
Changed title to reflect better understanding of the problem
UI focus/redraw/etc. issues usually are rather straightforward to debug by using remote-debugging. I.e. use a second PC (virtual is just enough) where your application runs.
See this MSDN article for details.
Run this in your form code behind. It will tell you which control has focus by giving you the type and name of the control. Run it in form_shown because its the last event in the form load process.
private void Form1_Shown(object sender, EventArgs e)
{
Control control = FindFocusedControl(this);
MessageBox.Show("The focused control " + control.Name + " is of type " + control.GetType());
}
public static Control FindFocusedControl(Control control)
{
var container = control as ContainerControl;
while (container != null)
{
control = container.ActiveControl;
container = control as ContainerControl;
}
return control;
}
If the answer isn't obvious after that, tell us what you get.
I've found a hack...er...I mean...workaround, that fixes the problem. The solution was buried in one of the comments of this answer (thanks, P. Brian Mackey, for providing the link to the related question!)
The workaround is to minimize the main window while the splash screen is displayed, then set it's WindowState back to Normal before showing the login form.
In the code below, see the lines commented with "HACK".
public class SingleInstanceController : WindowsFormsApplicationBase
{
public SingleInstanceController()
{
this.IsSingleInstance = true;
}
/// <summary>
/// When overridden in a derived class, allows a designer to emit code that
/// initializes the splash screen.
/// </summary>
protected override void OnCreateSplashScreen()
{
this.SplashScreen = new SplashScreen();
}
/// <summary>
/// When overridden in a derived class, allows a designer to emit code that configures
/// the splash screen and main form.
/// </summary>
protected override void OnCreateMainForm()
{
// SplashScreen will close after MainForm_Load completed
this.MainForm = new OfeMainForm();
// HACK - gets around problem with logon form not having focus on startup
// See also OfeMainForm_Shown in OfeMainForm.cs
this.MainForm.WindowState = FormWindowState.Minimized;
}
}
public partial class OfeMainForm : Form
{
// ...
private void OfeMainForm_Shown(object sender, EventArgs e)
{
// HACK - gets around problem with logon form not having focus on startup
// See also OnCreateMainForm in Program.cs
this.WindowState = FormWindowState.Normal;
OperatorLogon();
}
// ...
}
This is working for now, but I'm wondering if I should explicitly open the Logon form from the SingleInstanceController, rather than from my main form.

How do i check if an instance of the form already exists?

Im developing a plugin for Rhino, and when i run the command starting plugin i carries out the following. It creates a splash form, which has a timer on it, and after 2sec i loads another form.
If i by mistake click the plugin-icon again, it creates another instance of the spash form, which loads the plugin again.
How do i prevent this?
This is the code that makes the form.
public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
{
Splash Splash = new Splash();
Splash.Show();
return IRhinoCommand.result.success;
}
public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
{
if (!Application.OpenForms.OfType<Splash>().Any())
{
new Thread(() => Application.Run(new Splash())).Start();
}
return IRhinoCommand.result.success;
}

Categories