Page 1 of 1

Browsing for a file using OpenFileDialog

#1 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5529
  • View blog
  • Posts: 11,845
  • Joined: 02-June 10

Posted 26 July 2011 - 08:02 AM

*
POPULAR

The OpenFileDialog in its simplest form is really straight-forward and... well... simple.
But it also seems to be one of those controls that rarely gets used to its potential. So I thought I'd write something up to help you improve your use of it. Or maybe just show you how to use it for the first time if you haven't played with it before.

Just to be clear, an OpenFileDialog is a standard item available in your Visual Studio Toolbox.

Attached Image


It is the standard way a program allows a user to select one or more files.

Attached Image



Let's get started by making a simple test WinForms project. I called mine BrowsingForAFile
Attached Image


On our Form1 that Visual Studio so graciously started for us lets add:
  • A button whose .Name = btnLoad and .Text = "Load"
  • A textbox whose .Name = tbFilePath


Attached Image


In the designer double-click btnLoad to have Visual Studio stub out a method handler for the default event. The default event for a button is .Click so it will stub out a handler that will run when the user clicks the button. Then it will switch us to the code for the form automatically.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace BrowsingForAFile
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {

        }
    }
}



Notice that the method is already named after the button name. This is why we ALWAYS take the extra 2 seconds to rename our GUI controls as we put them on the form. Because Button1... Button2... Button43_Click... Is just not helpful or friendly to us, the developer that has to read the code.

If you are new, you are going to be tempted to put your functional code into this handler. Don't. It's a common rookie thing to do. But let's do it the right way so we don't learn bad habits that have to be un-learned later. The only thing we are going to do here is call a method who's purpose in life is to load a new file. So, right in the middle of this new method enter LoadNewFile(); but don't hit Enter yet. That's right, we are calling a method we haven't even created yet.

Attached Image

Notice how there is a little blue hint under the beginning of the method name. Hover over that with your mouse and you'll see an icon telling you there is a menu here for you.

Attached Image

Click on that and you'll see that Visual Studio is offering to build a stub of a method for you, that matches the signature of the call you just typed.

Attached Image

Click the menu item and let Visual Studio do some work for you.

Attached Image

Cool, eh?

Why did we want to do that? You ask. Why didn't we just put all of our code for opening the dialog right there in the button handler? Because we may want to load a file from more than one place. What if we want to add a menue with an Open File option? And a context menu... And maybe a menu off the TaskTray. By having a dedicated LoadFile method we can call it from a button, a menu, or programmatically when our application launches - without doing some really awkward coding to call the btnLoad_Click event handler. Which would be wrong anyway because the button wasn't clicked even though we wanted to load a file. This keeps things clean and proper without duplicating code.

Next we are going to add this public property
        public string userSelectedFilePath
        {
            get
            {
                return tbFilePath.Text;
            }
            set
            {
                tbFilePath.Text = value;
            }
        }



and then we are going to update the LoadFile() method to this
        private void LoadNewFile()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            System.Windows.Forms.DialogResult dr = ofd.ShowDialog();
            if (dr == DialogResult.OK)
            {
                userSelectedFilePath = ofd.FileName;
            }
        }


Go ahead and run it (F5).
Click the Load button and you should get a familiar and basic FileOpenDialog.
Pick a file and hit OK.

Attached Image


You will see the path in your textbox.

Attached Image


Hurray! It works. It's simple, but it works. I know you are wondering why we made the string property. Because we NEVER make GUI controls public. Its a bad habit. Sure this is just a little tutorial sample, but we don't build bad habits to unlearn. So we make a public property that can be accessed by any other class. The property handles its own housekeeping by accessing the private TextBox control.

Remember I said that the OpenFileDialog tends to be under used? Most times it seems it gets used as much as yo have right now. But it is capable of doing more for us. We are going to set values to a couple properties to make it much more friendly to the user. Let's assume we are still looking for images. Either .jpg, .bmp or .png files. And let's also assume the best place to get images is in the user's MyPictures directory. Shouldn't the OpenFileDialog do some of that for us? It should and it will. We set the .InitalDirectory property and .Filter property to achieve this.

Here is the update to the LoadFile() method
        private void LoadNewFile()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            string PictureFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            ofd.InitialDirectory = PictureFolder;
            ofd.Filter = "Pictures|*.jpg;*.bmp;*.png";
            System.Windows.Forms.DialogResult dr = ofd.ShowDialog();
            if (dr == DialogResult.OK)
            {
                userSelectedFilePath = ofd.FileName;
            }
        }
]


And here is the updated OpenFileDialog we get by setting these two properties.

Attached Image

Notice in the left pane that we start in the user's Pictures directory.
Notice just below the thumbnails that we are only looking for Pictures (*.jpg; *.bmp; *.png) and that the files shown really are limited to just those three extensions. Let's look at the format of the .Filters property a little more closely.

The .Filters property can take a long list of different filters, not just one. Here we used just one for demonstration and ease of reading. The format of the filter goes like this: Friendly name | extensions
So for us it was "Pictures|*.jpg; *.bmp; *.png" Note that a list of extension for one entry are separated by semicolons. If we want to extend the list of filters we do it all in one long string by repeating this pattern of
name|ext

"Pictures|*.jpg; *.bmp; *.png|Documents|*.txt; *.doc; *.log|All|*.*" to get us this:

Attached Image


Just in case you are lost at this point, here is all the code at once
Spoiler


But wait... There's more. It slices, it dices, it even handles more than one file at a time.
Personally, I always hate it when I have to browse multiple times to select multiple files from same directory. In this example what if we wanted the user to be able to select several images at once?

First we select our textbox and change its .Multiline property to true.
Then we resize it to accommodate more than one file path.
Then we update our code for the LoadFile() method.

Attached Image


Attached Image


        private void LoadNewFile()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            string PictureFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            ofd.InitialDirectory = PictureFolder;
            ofd.Title = "Pick a picture; any picture";
            ofd.CustomPlaces.Add(@"C:\");
            ofd.CustomPlaces.Add(@"C:\Program Files\");
            ofd.CustomPlaces.Add(@"K:\Documents\Pictures\");

            ofd.Multiselect = true;
            
            ofd.Filter = "Pictures|*.jpg; *.bmp; *.png|Documents|*.txt; *.doc; *.log|All|*.*";
            System.Windows.Forms.DialogResult dr = ofd.ShowDialog();
            if (dr == DialogResult.OK)
            {
                //userSelectedFilePath = ofd.FileName;
                foreach (string fileName in ofd.FileNames)
                {
                    userSelectedFilePath += fileName + Environment.NewLine;
                }
            }
        }



Notice we have also added some code to make use of the .CustomPlaces property, giving us some quick links in the left pane to destinations we may know the user needs. Maybe our program has a backup directory on a second drive... or a server path that we don't need to force the user into 30 different clicks to drill down to... or a directory the program makes to save it's own theme files.
Attached Image



Giving us the final version of our OpenFileDialog for this tutorial.

Attached Image


Attached Image

Hopefully this has helped you out and made you less affraid to explore the possibilities of the built-in controls. By taking a little time to read up on the controls and finding all of their features you can save yourself a lot of work. For example, if you read up on the OpenFileDialog you will find several more feature such as confirming that a file exists (because the user might have typed the path wrong). Or have the OpenFileDialog add an extension if the user forgets it.

This post has been edited by tlhIn`toq: 26 July 2011 - 08:23 AM


Is This A Good Question/Topic? 12
  • +

Replies To: Browsing for a file using OpenFileDialog

#2 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4490
  • View blog
  • Posts: 7,822
  • Joined: 08-June 10

Posted 26 July 2011 - 09:14 AM

Ok, the scifi nerd in me has to point out that you have a picture of Serenity in that first folder, and that's just awesome.




The programmer nerd reminds me that this is a good tutorial. I'll add it to the resources thread.
Was This Post Helpful? 0
  • +
  • -

#3 Happyhour  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 12-April 11

Posted 27 July 2011 - 01:52 AM

I always enjoy your tutorials, so many pictures :D
Was This Post Helpful? 0
  • +
  • -

#4 cfsharp  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 10
  • Joined: 29-May 11

Posted 29 July 2011 - 06:43 PM

I like this tutorial, simple, but very very helpful!
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1