Using the Open File Dialog Window - Page 4
       by kirupa  |  7 August 2007

In the previous page, we wrapped up opening multiple files using our Open File dialog window. Let's wrap up this tutorial by discussing an issue that exists with WPF in Vista when displaying the Open File dialog.

Fixing OpenFileDialog under Windows Vista
If you take a close look at the OpenFileDialog under Windows Vista, you'll find that it looks out of place with its old-school style and low quality icons:

[ the old-school Open File dialog window ]

This is actually not a feature. To display the proper OpenFileDialog in Windows Vista and earlier versions, one solution is to call the WinForms version of OpenFileDialog. To do that, first you will need to add a reference to System.Windows.Forms. From your Solution Explorer in Visual Studio / C# Express, right click on the References folder and select Add Reference:

[ we need to add a reference to your project ]

After you have selected the Add Reference menu item, the Add Reference window will appear. From this window, make sure the .NET tab is selected. Scroll down until you find the System.Windows.Forms Component Name:

[ let's add the System.Windows.Forms namespace ]

Select System.Windows.Forms and press OK to add the reference to this component and to close the Add Reference window.

Now that your reference has been added, we need to add a new using statement to get our C# file to use components stored in System.Windows.Forms. In your Window1.xaml.cs file (which should be open anyway), add the System.Windows.Forms namespace to your list of using statements:

using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using Microsoft.Win32;
using System.Windows.Forms;

After you have added your new using statement, press F6 to build your application. You will notice that you now receive a few errors:

[ two errors now appear because of an incompatibility ]

The errors are caused because the OpenFileDialog class exists in both your Microsoft.Win32 namespace as well as you newly added System.Windows.Forms namespace. To resolve this problem, right click on each instance of the OpenFileDialog class in your code, select Resolve, and from the next menu, select System.Windows.Forms.OpenFileDialog:

[ select your OpenFileDialog window ]

You'll need to repeat the above process for each OpenFileDialog instance that exists in your code. For example, this is how my code now looks like:

private void WindowLauncher(object sender, RoutedEventArgs e)
{
System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
ofd.Multiselect = true;
 
ofd.Filter = "Data Sources (*.txt, *.xml)|*.txt*;*.xml|All Files|*.*";
 
if (ofd.ShowDialog() == true)
{
string[] filePath = ofd.FileNames;
string[] safeFilePath = ofd.SafeFileNames;
}
}

Notice that OpenFileDialog object declaration and initialization explicitly maps out the path through System.Windows.Forms to avoid the ambiguity that exists with the similar OpenFileDialog that exists in Microsoft.Win32.

When you build your application again, you'll run into another error. This time, our earlier code where we check if our dialog window returns a true for opening a file no longer works. In the WinForms version of OpenFileDialog, you'll need to explicitly select your dialog window's OK button as having been pressed, and you can do that via the WinForms DialogResult enum:

private void WindowLauncher(object sender, RoutedEventArgs e)
{
System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
ofd.Multiselect = true;
 
ofd.Filter = "Data Sources (*.txt, *.xml)|*.txt*;*.xml|All Files|*.*";
 
 
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string[] filePath = ofd.FileNames;
string[] safeFilePath = ofd.SafeFileNames;
}
}

Notice that instead of checking if ShowDialog returns true, I check to see if it was the OK button that was used to close the dialog window. If you build and run your application again, you will not receive any errors. If you are running a non-Vista version of Windows, you'll display the usual Open File dialog window, but if you are running Vista, you will see the more native Open File dialog window instead:

[ the correct, proper version of the Open File dialog window ]

Why Bother Using the Win32 Version?
A valid question would be to ask why the Win32 version should even be used when dealing with dialog windows. The main reason is that all dialog windows including the Windows.Forms versions, internally call the same lower level implementation of the dialog window. Ideally, it should not matter whether you create your OpenFileDialog object using the Win32 namespace or the Windows.Forms namespace. The end result should be that the best version of the dialog window that can be displayed by your OS should be displayed.

I believe that future versions of WPF will fix this inconsistency, so hopefully you will not have to create this workaround using Windows.Forms inside a WPF application in the future. A fix would automatically cause any WPF applications that use the currently-incorrect Win32 calls to automatically display the new version. If you are willing to risk the wait, you can use the default Win32 approach and automatically display the new windows when the fix is made. If you want to provide a good UI now, you can make the call to the dialog window using Windows.Forms as described in this page.

For a more detailed look at why the Win32 version of OpenFileDialog still displays the legacy window, check out my blog entry on this topic.


Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!

Kirupa's signature!

 

 

1 | 2 | 3 | 4




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.