Hash

Entries tagged as ‘WinForms’

C# Winforms: Using a progress bar with Web Browser Control

March 31, 2009 · 2 Comments

The .NET web browser provides a number of different events including some which tells when the browser started navigating to a web page and when that navigation completed.

These events are:

private System.Windows.Forms.WebBrowser ItemBrowser;

 

this.ItemBrowser.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.ItemBrowser_Navigating);
this.ItemBrowser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.ItemBrowser_DocumentCompleted);
this.ItemBrowser.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(this.ItemBrowser_Navigated);

 

This shows the functions are being called at proper events. Now let us come to the code in those functions. The goal is to show a marquee in the status bar when a page is clicked and stop that marquee when navigation is fully complete.

private void ItemBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
    BrowserLabel.Text = "Loading ... ";
    BrowserProgressBar.MarqueeAnimationSpeed = 80;
    BrowserProgressBar.Style = ProgressBarStyle.Marquee;
}

 

I have created two items in the status strip. A Label named BrowserLabel and a progress bar item named BrowserProgressBar. The text property of BrowserLabel is set to “Loading … “ when a hyperlink is created. And to start the marquee we set the style of progress bar to Marquee and its speed to 80. Note that as you increase the AnimationSpeed it will slow down. It will be fastest at 1 and slowest at 100 (I have set 100 as MaxSpeed, you can change that property as well).

Now we need to stop this animation when browsing is complete:

void ItemBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    BrowserProgressBar.MarqueeAnimationSpeed = 0;
    BrowserProgressBar.Style = ProgressBarStyle.Blocks;

    BrowserLabel.Text = "Ready";
}

 

I set the style back to Block and AnimationSpeed to “0”. Style is a property and it can start/stop the animation according to its value so you don’t need to call a “start” function as required in the previous versions. Also the value of Label is reset here.

One function is still remaining:

void ItemBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    if (!ItemBrowser.IsBusy)
    {
        BrowserProgressBar.MarqueeAnimationSpeed = 0;
        BrowserProgressBar.Style = ProgressBarStyle.Blocks;

        BrowserLabel.Text = "Ready";
    }
}

 

This function is also called when navigation is completed. Although in most cases the DocumentCompleted function is sufficient but bookmark links do not call that function so Navigated function will do in those cases.

 

Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!

Categories: .NET · CodeProject
Tagged: , , , , , , , , , ,

C# Winforms: Create a Single Instance Form Using Singleton

March 31, 2009 · 8 Comments

A common practice in WinForms programming is to keep only one instance of a certain form in the application. A new instance of that form is never created and shown. I have previously written a small note on this topic and gave a solution here which I personally don’t like.

In this post I am presenting a much better solution which is based on the singleton pattern. Rather than each time looking for the form in a list of opened forms I make the constructor private.

Let us start with the Form:

public sealed partial class ThirdForm : Form
{

}

The class is sealed so it cannot be inherited. We don’t want a child create an instance of this class multiple times.

Now add these members and methods to the class:

private static readonly ThirdForm MyInstance = new ThirdForm();

This is the sole instance of this form. And the private constructor to avoid multiple instances outside the class:

private ThirdForm()
{
    InitializeComponent();
}

And the property to publish the sole instance:

public static ThirdForm OnlyInstance
{
    get { return MyInstance; }
}

Another functionality that you might want to add to your Form is a new Show method. And you may also want to know whether the form was already opened or your opened it. Here is the answer to these questions. Add this code to your form class to Show() or Select() if already shown.

public new void Show()
{
    if (IsShown)
        base.Show();
    else
    {
        base.Show();
        IsShown = true;
    }
}

A variable IsShown of type bool is added to the form to record the current state.

private static bool IsShown = false;

static ThirdForm()
{
    OnlyInstance.FormClosing += new FormClosingEventHandler(OnlyInstance_FormClosing);
}

private static void OnlyInstance_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = true;
    IsShown = false;

    OnlyInstance.Hide();
}

The variable IsShown is set to false when the only instance of this form is closed. But remember its a singleton. We can’t let the only instance die so we catch FormClosing event and Hide() the form instead of closing it.

This solution looks elegant than looking for an opened form in an array but it has draw backs. You cannot catch the FormClosed event because it will never happen. The form is created only once so if your form is based on some volatile objects you will never see the change even if you close and open it again. May be I try to address these problems in another post some day. Spot On!

Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!

Categories: .NET
Tagged: , , , , , , , , ,

C#: Disallow multiple instances of your application. The Mutex way.

February 2, 2009 · 3 Comments

Previously I used the Process class to find out if a process with the same name is already running. Here is the link.

But that method had a problem. The code could easily be dodged by renaming the assembly. The Process class would give a different name the next time and a new instance will be started.

Now I have come up with the mutex which is much safer. Every time the application is started we check for a certain mutex. If the mutex exists we error out. Otherwise we go ahead, create that special mutex for our successors and run the application. Dont forget to release that mutex when application is about to exit.

try
{
    SingleInstanceMutex = Mutex.OpenExisting("TickerMutex0");
    Process.GetCurrentProcess().Kill();
}
catch (Exception ex)
{
    SingleInstanceMutex = new Mutex(false, "TickerMutex0");
}

If the OpenExisting method fails to open it will throw an exception which is fine. We create the mutex in this case and go on. And if a valid mutex is found, we simply close. The SingleInstanceMutex is a private member of the class of System.Threading.Mutex type. The Mutex is released when application is closed so we need to catch the Application_Exit event.

Application.ApplicationExit += new EventHandler(Application_ApplicationExit);

The body of Application_ApplicationExit function is:

void Application_ApplicationExit(object sender, EventArgs e)
{
    try
    {
        SingleInstanceMutex.ReleaseMutex();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

 

 

 

I am using the Process.Kill method here because there is some special code in Application_Exit event which I dont want to run everytime.

Categories: .NET
Tagged: , , , , , , , , ,

C# Winforms: Disallow multiple instances of your application

January 29, 2009 · 4 Comments

I have found the following solution to disallow multiple instances of my WinForms application:

using System.Diagnostics;
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
{
     Process.GetCurrentProcess().Kill();
}

This works for me but I am not sure if this is the right mechanism. My gut feeling is that this can easily be dogded but I am not sure HOW. Anyone?

Categories: .NET
Tagged: , , , , , , , ,