This article is currently in the process of being translated into Croatian (~31% done).
The OpenFileDialog
Kad god otvorite ili spremite datoteku u gotovo svakoj Windows aplikaciji, vidjet ćete otprilike iste dijaloge za to. Razlog je naravno što su ti dijalozi dio Windows API-ja te su stoga dostupni i programerima na Windows platformi.
Za WPF, standardne dijaloge za otvaranje i spremanje datoteka ćete naći u Microsoft.Win32 imenovanom prostoru. U ovom članku fokusirat ćemo se na OpenFileDialog klasu, koja čini jednostavnim prikazivanje dijaloga za otvaranje jedne ili više datoteka.
Jednostavni OpenFileDialog primjer
Započnimo s korištenjem OpenFileDialog bez dodatnih opcija, kako bi učitali datoteku u TextBox kontrolu:
<Window x:Class="WpfTutorialSamples.Dialogs.OpenFileDialogSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OpenFileDialogSample" Height="300" Width="300">
<DockPanel Margin="10">
<WrapPanel HorizontalAlignment="Center" DockPanel.Dock="Top" Margin="0,0,0,10">
<Button Name="btnOpenFile" Click="btnOpenFile_Click">Open file</Button>
</WrapPanel>
<TextBox Name="txtEditor" />
</DockPanel>
</Window>
using System;
using System.IO;
using System.Windows;
using Microsoft.Win32;
namespace WpfTutorialSamples.Dialogs
{
public partial class OpenFileDialogSample : Window
{
public OpenFileDialogSample()
{
InitializeComponent();
}
private void btnOpenFile_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if(openFileDialog.ShowDialog() == true)
txtEditor.Text = File.ReadAllText(openFileDialog.FileName);
}
}
}
Nakon što kliknete na "Open file" dugme, OpenFileDialog će biti instanciran i prikazan. Ovisno o verziji Windowsa koju koristite i odabrane teme, dijalog će nalikovati na nešto poput ovog:
Metoda ShowDialog() će vratiti vrijednost nullable boolean tipa, što znači da može biti false, true ili null. Ako korisnik odabere datoteku i pritisne "Otvori", rezultat će biti True, i u tom slučaju pokušavamo učitati datoteku u TextBox kontrolu. Potpunu putanju odabrane datoteke dobivamo korištenjem svojstva FileName klase OpenFileDialog."
Filter
Obično kada želite da korisnik otvori neku datoteku u vašoj aplikaciji, želite to ograničiti na jedan ili nekoliko tipova datoteka. Primjerice, Word uglavnom otvara Word datoteke (s ekstenzijom .doc ili .docx), a Notepad obično otvara tekstualne datoteke (s ekstenzijom .txt).
Možete specificirati filter za vaš OpenFileDialog kako biste ukazali korisniku koje tipove datoteka može otvoriti u vašoj aplikaciji te kako biste ograničili prikazane datoteke radi bolje preglednosti. To se radi s pomoću Filter svojstva, kojeg možemo na sljedeći način dodati gornjem primjeru nakon što se inicijalizira dijalog:
openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
Ovo je rezultat:
Notice how the dialog now has a combo box for selecting the file types, and that the files shown are limited to ones with the extension(s) specified by the selected file type.
The format for specifying the filter might look a bit strange at first sight, but it works by specifying a human-readable version of the desired file extension(s) and then one for the computer to easily parse, separated with a pipe (|) character. If you want more than one file type, as we do in the above example, each set of information are also separated with a pipe character.
So to sum up, the following part means that we want the file type to be named "Text files (*.txt)" (the extension in the parenthesis is a courtesy to the user, so they know which extension(s) are included) and the second part tells the dialog to show files with a .txt extension:
Text files (*.txt)|*.txt
Each file type can of course have multiple extensions. For instance, image files could be specified as both JPEG and PNG files, like this:
openFileDialog.Filter = "Image files (*.png;*.jpeg)|*.png;*.jpeg|All files (*.*)|*.*";
Simply separate each extension with a semicolon in the second part (the one for the computer) - in the first part, you can format it the way you want to, but most developers seem to use the same notation for both parts, as seen in the example above.
Setting the initial directory
The initial directory used by the OpenFileDialog is decided by Windows, but by using the InitialDirectory property, you can override it. You will usually set this value to a user specified directory, the application directory or perhaps just to the directory last used. You can set it to a path in a string format, like this:
openFileDialog.InitialDirectory = @"c:\temp\";
If you want to use one of the special folders on Windows, e.g. the Desktop, My Documents or the Program Files directory, you have to take special care, since these may vary from each version of Windows and also be dependent on which user is logged in. The .NET framework can help you though, just use the Environment class and its members for dealing with special folders:
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
In this case, I get the path for the My Documents folder, but have a look at the SpecialFolder enumeration - it contains values for a lot of interesting paths. For a full list, please see this MSDN article.
Multiple files
If your application supports multiple open files, or you simply want to use the OpenFileDialog to select more than one file at a time, you need to enable the Multiselect property. In the next example, we've done just that, and as a courtesy to you, dear reader, we've also applied all the techniques mentioned above, including filtering and setting the initial directory:
<Window x:Class="WpfTutorialSamples.Dialogs.OpenFileDialogMultipleFilesSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OpenFileDialogMultipleFilesSample" Height="300" Width="300">
<DockPanel Margin="10">
<WrapPanel HorizontalAlignment="Center" DockPanel.Dock="Top" Margin="0,0,0,10">
<Button Name="btnOpenFile" Click="btnOpenFiles_Click">Open files</Button>
</WrapPanel>
<ListBox Name="lbFiles" />
</DockPanel>
</Window>
using System;
using System.IO;
using System.Windows;
using Microsoft.Win32;
namespace WpfTutorialSamples.Dialogs
{
public partial class OpenFileDialogMultipleFilesSample : Window
{
public OpenFileDialogMultipleFilesSample()
{
InitializeComponent();
}
private void btnOpenFiles_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = true;
openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if(openFileDialog.ShowDialog() == true)
{
foreach(string filename in openFileDialog.FileNames)
lbFiles.Items.Add(Path.GetFileName(filename));
}
}
}
}
If you test this code, you will see that you can now select multiple files in the same directory, by holding down either Ctrl orShift and clicking with the mouse. Once accepted, this example simply adds the filenames to the ListBox control, by looping through the FileNames property.
Summary
As you can see, using the OpenFileDialog in WPF is very easy and really takes care of a lot of work for you. Please be aware that to reduce the amount of code lines, no exception handling is done in these examples. When working with files and doing IO tasks in general, you should always look out for exceptions, as they can easily occur due to a locked file, non-existing path or related problems.