This article has been localized into Polish by the community.
A special thanks goes out to user #2764 for the Polish translation of this article: Krzysztof Jaskulski
Okno dialogowe "Otwórz plik"
Niemal w każdej aplikacji systemu Windows, za każdym razem gdy otwierasz lub zapisujesz plik, zobaczysz mniej więcej te same okna dialogowe. Powodem tego jest oczywiście to, że owe okna dialogowe są częścią API Windows i dlatego też są również dostępne dla programistów na platformie Windows.
We frameworku WPF standardowe okna dialogowe otwierania i zapisywania plików znajdują się w przestrzeni nazw "Microsoft.Win32". W tym artykule skupimy się na klasie "OpenFileDialog", która umożliwia w bardzo prosty sposób wyświetlenie okna dialogowego służącego do otwierania jednego lub wielu plików.
Prosty przykład z oknem "Otwórz plik"
Zacznijmy od użycia okna "OpenFileDialog" bez żadnych dodatkowych opcji, aby jedynie otworzyć wskazany plik i przedstawić jego zawartość w kontrolce TextBox:
<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);
}
}
}
Po kliknięciu przycisku "Open file", okno "OpenFileDialog" zostanie utworzone i wyświetlone. W zależności od tego jakiej wersji systemu Windows używasz i od wybranego motywu, owe okno będzie wyglądało mniej więcej w ten sposób:
Metoda ShowDialog() zwróci wartość bool, co oznacza że może to być wartość false, true lub null. Jeżeli użytkownik wybierze plik i wciśnie przycisk "Open" zwrócona zostanie wartość "true" i wtedy podjęta zostanie próba przedstawienia zawartości owego pliku w kontrolce TextBox "txtEditor". Pełną ścieżkę dostępu do wybranego pliku otrzymujemy korzystając z właściwości FileName okna OpenFileDialog.
Filtr
Zazwyczaj gdy pozwalasz, aby użytkownik otworzył plik w aplikacji, chciałbyś ograniczyć jego wybór do jednego lub kilku rodzajów plików. Na przykład program "Microsoft Word" otwiera głównie pliki typu "Word" (z rozszerzeniem .doc lub .docx), a program "Notepad" otwiera głównie pliki tekstowe (z rozszerzeniem .txt).
Możesz zdefiniować filtr dla okna "OpenFileDialog", aby wskazać użytkownikowi, które rodzaje plików powinny być otwierane w danej aplikacji. Jednocześnie ograniczasz w ten sposób liczbę wyświetlanych plików co daje bardziej przejrzysty widok dostępnych do wyboru plików. Filtr definiujemy za pomocą właściwości "Filter", którą możemy dodać do powyższego przykładu zaraz po utworzeniu okna dialogowego, w ten oto sposób:
openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
Oto rezultat zastosowania takiej instrukcji
Zauważ, że w oknie dialogowym pojawiła się teraz kontrolka "ComboBox" służąca do określenia wybieranych rodzajów plików, a widok dostępnych do wyboru plików jest ograniczony do tych z rozszerzeniem(ami) zgodnym z wybranym typem.
Struktura definicji filtra może wydawać się nieco dziwna na pierwszy rzut oka. Jest tak dlatego, że składa się ona z dwóch części. Pierwsza część jest wersją w pełni czytelną i przeznaczoną dla użytkownika. Druga część jest instrukcją czytelną dla komputera. Obie części są rozdzielone znakiem separatora "|". Jeśli chcesz zdefiniować więcej niż jeden rodzaj pliku, jak zrobiliśmy to w powyższym przykładzie, to każde kolejne definicje należy dołączać oddzielając je od siebie również znakiem separatora "|".
Podsumowując, przytoczony poniżej wycinek definicji oznacza, że chcemy aby rodzaj pliku został wyświetlony pod nazwą "Text files (*.txt)" (rozszerzenie podane w nawiasie jest uprzejmością dla użytkownika, aby wiedział które rozszerzenia są brane pod uwagę), a dalsza część mówi oknu dialogowemu, aby wyświetlić jedynie pliki z rozszerzeniem ".txt":
Text files (*.txt)|*.txt
Każdy rodzaj pliku może oczywiście obejmować grupę wielu rozszerzeń. Na przykład, pliki graficzne mogą obejmować zarówno pliki "JPEG" jak i "PNG". Pokazuje to poniższa definicja:
openFileDialog.Filter = "Image files (*.png;*.jpeg)|*.png;*.jpeg|All files (*.*)|*.*";
W drugiej części definicji (tej dla komputera) oddzielamy po prostu od siebie każde rozszerzenie pliku średnikiem. W pierwszej części definicji możesz to zrobić w dowolny sposób, ale większość programistów zwykle używa tego samego zapisu dla obu części, co widać w powyższym przykładzie.
Ustawienie katalogu domyślnego
Katalog domyślny używany przez okno "OpenFileDialog" jest ustalany przez system Windows, ale dzięki użyciu właściwości "InitialDirectory" możemy go zmienić na własny. Zazwyczaj ustawia się tę właściwość na katalog jaki zażyczy sobie użytkownik, na katalog aplikacji lub po prostu na ostatnio używany katalog. Można go ustawić podając wprost ścieżkę dostępu w standardowym formacie zapisu, w ten sposób:
openFileDialog.InitialDirectory = @"c:\temp\";
Jeżeli chcesz wykorzystać jeden z folderów specjalnych w systemie Windows, np. "Desktop", "My Documents" lub "Program Files", musisz zachować szczególną ostrożność, ponieważ mogą się one różnić w zależności od używanej wersji systemu Windows i są uzależnione od tego, który użytkownik jest zalogowany. Framework .NET przychodzi nam jednak z pomocą. Wystarczy użyć klasy "Environment" i jej stałych wyliczeniowych "SpecialFolder":
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
W przytoczonym przykładzie otrzymujemy ścieżkę do katalogu "My Documents", ale spójrzmy na stałą wyliczeniową "SpecialFolder" - zawiera ona wartości dające ścieżki dostępu do wielu interesujących katalogów. Pełna lista znajduje się w tym artykule MSDN.
Wybór wielu plików
Jeśli twoja aplikacja potrafi otworzyć wiele plików na raz lub po prostu chcesz użyć okna "OpenFileDialog" do wskazania więcej niż jednego pliku na raz, musisz włączyć tę opcję poprzez właściwość "Multiselect". W przykładzie poniżej zrobiliśmy tak właśnie i jako uprzejmość dla Ciebie, drogi czytelniku, zastosowaliśmy również wszystkie wymienione wcześniej techniki, w tym filtrowanie i ustawienie katalogu domyślnego:
<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));
}
}
}
}
Jeśli przetestujesz ten kod, to zobaczysz że teraz możesz zaznaczać wiele plików w tym samym katalogu dzięki przytrzymaniu wciśniętego klawisza "Ctrl" lub "Shift" podczas klikania myszką na pliki. Po zaakceptowaniu swojego wyboru, przykład ten zwyczajnie dodaje ścieżki dostępu do wskazanych plików do kontrolki ListBox "lbFiles", poprzez zastosowaną pętlę foreach przeglądającą zawartość kolekcji "FileNames".
Podsumowanie
Jak widać, korzystanie z okna "OpenFileDialog" w WPF jest bardzo proste i naprawdę wykonuje wiele pracy za Ciebie. Należy pamiętać, że aby zmniejszyć ilość kodu w tych przykładach nie zastosowano żadnej obsługi wyjątków. Podczas pracy z plikami i wykonywania zadań typu IO w ogólności, należy zawsze stosować obsługę wyjątków, ponieważ mogą one często się pojawiać z powodu braku dostępu do pliku, nieistniejącej ścieżki dostępu i innych podobnych powodów.