VB.NET SaveFileDialog – Save Files with Dialog (2026)
The VB.NET SaveFileDialog lets users pick a file name and location before your application writes data to disk. It handles path selection, file type filtering, and overwrite confirmation in a single control. This guide covers setup, filters, default paths, common patterns, and integration with actual file writing.
Inhaltsverzeichnis
- 1 What is the SaveFileDialog?
- 2 Basic example
- 3 Setting up file type filters
- 4 Setting the default folder and file name
- 5 Overwrite confirmation
- 6 Complete example: saving a text file
- 7 Saving binary files (images, PDFs)
- 8 Saving with a StreamWriter (large files)
- 9 All important properties at a glance
- 10 Common mistakes
- 11 FAQ
- 12 Wrapping up
What is the SaveFileDialog?
The SaveFileDialog is a WinForms control from System.Windows.Forms. When you call ShowDialog(), it opens the standard Windows „Save As“ dialog. The user picks a folder, enters a file name, and clicks Save. Your code then receives the full file path through the FileName property.
Use it when:
- The user should choose where to save a file (exports, reports, downloads)
- You need a file type filter (e.g. only .txt, .csv, or .pdf)
- You want built-in overwrite confirmation without writing your own
Basic example
The simplest SaveFileDialog with a single file type:
Using dlg As New SaveFileDialog()
dlg.Filter = "Text files (*.txt)|*.txt"
dlg.Title = "Save text file"
If dlg.ShowDialog() = DialogResult.OK Then
File.WriteAllText(dlg.FileName, "Hello World")
End If
End Using
The Using block disposes the dialog after use. ShowDialog() returns DialogResult.OK when the user clicks Save, or DialogResult.Cancel when they close the dialog. Always check the result before writing.
Setting up file type filters
The Filter property controls which file types appear in the dropdown. The syntax is Description|Pattern, separated by pipes for multiple types:
' Single filter dlg.Filter = "Text files (*.txt)|*.txt" ' Multiple filters dlg.Filter = "Text files (*.txt)|*.txt|CSV files (*.csv)|*.csv|All files (*.*)|*.*" ' Pre-select the second filter (1-based index) dlg.FilterIndex = 2
Each filter entry consists of two parts: the display text (e.g. „Text files (*.txt)“) and the actual pattern (e.g. „*.txt“). FilterIndex is 1-based, so 2 selects the second entry.
Automatically adding the file extension
' Append extension if user doesn't type one (default: True) dlg.AddExtension = True ' Set default extension (without the dot) dlg.DefaultExt = "txt"
With AddExtension = True (the default), if the user types „report“ without an extension, the dialog appends „.txt“ based on the selected filter or the DefaultExt value.
Setting the default folder and file name
Using dlg As New SaveFileDialog()
' Start in the user's Documents folder
dlg.InitialDirectory = Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments)
' Pre-fill the file name
dlg.FileName = "report-2026.csv"
dlg.Filter = "CSV files (*.csv)|*.csv"
If dlg.ShowDialog() = DialogResult.OK Then
File.WriteAllText(dlg.FileName, csvContent)
End If
End Using
InitialDirectory sets where the dialog opens. Common choices:
Environment.SpecialFolder.MyDocumentsfor user documentsEnvironment.SpecialFolder.Desktopfor the desktop- The application path for saving next to the executable
If you don’t set InitialDirectory, the dialog remembers the last folder the user navigated to during the current session.
Overwrite confirmation
' Show a warning when the file already exists (default: True) dlg.OverwritePrompt = True
This is enabled by default. When the user selects an existing file, Windows shows a confirmation dialog asking if they want to replace it. You don’t need to code this yourself.
Complete example: saving a text file
A realistic example that saves a multi-line text file with encoding support, using WriteAllText:
Imports System.IO
Imports System.Text
Private Sub BtnSave_Click(sender As Object, e As EventArgs) Handles BtnSave.Click
Using dlg As New SaveFileDialog()
dlg.Title = "Save report"
dlg.Filter = "Text files (*.txt)|*.txt|CSV files (*.csv)|*.csv"
dlg.InitialDirectory = Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments)
dlg.FileName = $"report-{DateTime.Now:yyyy-MM-dd}"
If dlg.ShowDialog() = DialogResult.OK Then
Dim content As String = BuildReport()
File.WriteAllText(dlg.FileName, content, Encoding.UTF8)
MessageBox.Show($"Saved to {dlg.FileName}",
"Success", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Using
End Sub
Always specify Encoding.UTF8 when writing text files. Without it, .NET uses the system default encoding, which can cause issues with special characters on other machines.
Saving binary files (images, PDFs)
SaveFileDialog works the same way for binary content. The only difference is the write method:
' Save an image
Using dlg As New SaveFileDialog()
dlg.Filter = "PNG images (*.png)|*.png|JPEG images (*.jpg)|*.jpg"
dlg.FileName = "screenshot"
If dlg.ShowDialog() = DialogResult.OK Then
PictureBox1.Image.Save(dlg.FileName)
End If
End Using
' Save a byte array (e.g. downloaded PDF)
Using dlg As New SaveFileDialog()
dlg.Filter = "PDF files (*.pdf)|*.pdf"
If dlg.ShowDialog() = DialogResult.OK Then
File.WriteAllBytes(dlg.FileName, pdfBytes)
End If
End Using
Saving with a StreamWriter (large files)
For large files or line-by-line writing, use a StreamWriter with the path from the dialog:
Using dlg As New SaveFileDialog()
dlg.Filter = "CSV files (*.csv)|*.csv"
If dlg.ShowDialog() = DialogResult.OK Then
Using writer As New StreamWriter(dlg.FileName, False, Encoding.UTF8)
writer.WriteLine("Name,Email,Age")
For Each contact In contacts
writer.WriteLine($"{contact.Name},{contact.Email},{contact.Age}")
Next
End Using
End If
End Using
The StreamWriter approach is more memory-efficient for large datasets because it writes line by line instead of building the entire string in memory first. For a deeper look at text file operations, see the VB.NET Write Text File guide.
All important properties at a glance
| Property | Default | Purpose |
|---|---|---|
Filter | (empty) | File type dropdown entries |
FilterIndex | 1 | Pre-selected filter (1-based) |
FileName | (empty) | Pre-filled file name / selected path after dialog |
InitialDirectory | (empty) | Starting folder |
DefaultExt | (empty) | Extension added when user omits one |
AddExtension | True | Auto-append extension from filter |
OverwritePrompt | True | Warn before overwriting existing files |
Title | „Save As“ | Dialog window title |
ValidateNames | True | Reject invalid file name characters |
Common mistakes
Writing without checking DialogResult
' BAD - writes to empty path if user cancels
dlg.ShowDialog()
File.WriteAllText(dlg.FileName, content)
' GOOD - check the result first
If dlg.ShowDialog() = DialogResult.OK Then
File.WriteAllText(dlg.FileName, content)
End If
Forgetting the Using block
The SaveFileDialog holds unmanaged resources (a Windows COM object). Without Using, those resources stay in memory until the garbage collector runs. Always wrap it in a Using block.
Broken filter syntax
' BAD - missing pattern after pipe dlg.Filter = "Text files|" ' BAD - using comma instead of pipe dlg.Filter = "Text files (*.txt), *.txt" ' GOOD - correct description|pattern syntax dlg.Filter = "Text files (*.txt)|*.txt"
A broken Filter string throws an ArgumentException at runtime. The pattern is always Display text|*.extension, with a pipe separating each pair.
FAQ
Create a New SaveFileDialog() inside a Using block, set the Filter property, then call ShowDialog(). Check if the result equals DialogResult.OK before writing to dlg.FileName.
Set the FileName property before calling ShowDialog(). For example: dlg.FileName = "report.csv". The user can still change it in the dialog.
Set the Filter property with the pattern Description|*.ext. For multiple types, separate them with pipes: "Text (*.txt)|*.txt|CSV (*.csv)|*.csv".
No. The dialog only lets the user pick a path and file name. You are responsible for writing the file yourself using methods like File.WriteAllText() or File.WriteAllBytes() with the path from dlg.FileName.
SaveFileDialog lets the user pick a destination for writing a new file, with overwrite confirmation built in. OpenFileDialog lets the user pick an existing file to read. Both return the selected path through the FileName property.
Wrapping up
The SaveFileDialog gives your VB.NET application a native file-save experience with minimal code. Set a Filter for file types, use InitialDirectory for the starting folder, and always check DialogResult.OK before writing. For the actual file writing, use File.WriteAllText() for text or File.WriteAllBytes() for binary data. Need to read files instead? The OpenFileDialog follows the same pattern in reverse. For more on writing text files, see the VB.NET Write Text File guide.