UI is blocked, because you are running login code in UI thread. To avoid that, you may use 'BackgroundWorker', or if you're using 4 or 4.5 .NET you may use 'Tasks' to move your login stuff to another thread to avoid UI blocking.
If Windows Forms and .NET 4+, following may work:
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Visible = true;
Task.Factory.StartNew(Login)
.ContinueWith(t =>
{
progressBar1.Visible = false;
}, TaskScheduler.FromCurrentSynchronizationContext());
}
private static void Login()
{
// should replace this with actual login stuff
Thread.Sleep(TimeSpan.FromSeconds(3));
}
What it does, it moves Login processing to another thread, so UI thread is not blocked. Before staring login, it unhides progress bar, which has style set to marque and after Login is finished, it hides progress bar again.
As long as UI is not blocked, user is allowed to input/press anything he wants during login, so solution would be either disable all controls before login or show progress bar in separate modal form, in such way user won't see application as hanged and won't be able to do any input until progress bar form will be closed.
Update: added example with separate progress form:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MarqueeForm.DoWithProgress("Doing login", Login);
}
private static void Login()
{
Thread.Sleep(TimeSpan.FromSeconds(3));
}
}
public class MarqueeForm : Form
{
private Label label;
public MarqueeForm()
{
var progressBar = new ProgressBar
{
Style = ProgressBarStyle.Marquee,
Top = 20,
Size = new Size(300, 15)
};
Controls.Add(progressBar);
label = new Label();
Controls.Add(label);
}
public static void DoWithProgress(string title, Action action)
{
var form = new MarqueeForm
{
Size = new Size(310, 50),
StartPosition = FormStartPosition.CenterParent,
FormBorderStyle = FormBorderStyle.FixedDialog,
ControlBox = false,
label = { Text = title }
};
form.Load += (sender, args) =>
Task.Factory.StartNew(action)
.ContinueWith(t => ((Form)sender).Close(),
TaskScheduler.FromCurrentSynchronizationContext());
form.Show();
}
}