Many applications need to display dialogs to let the user select certain standard pieces of information. Probably the most common dialogs let the user select a file to open and select a file to save into. Other dialogs let the user select colors, filesystem folders, fonts, and printers for printing.
Closely related to the print dialog are the print preview dialog (which lets the user see a preview of a printout before sending it to the printer, possibly saving paper if the user then cancels the printout) and the page setup dialog (which lets the user select things like margins before printing).
You could build all of these dialogs yourself (or you will be able to once you've finished reading this book), but why should you? If so many programs need the exact same features, why shouldn't someone build standard dialogs that everyone can use?
Happily that's exactly what Microsoft did.
C# comes with the following standard dialogs that handle these common tasks:
ColorDialog
FolderBrowserDialog
FontDialog
OpenFileDialog
PageSetupDialog
PrintDialog
PrintPreviewDialog
SaveFileDialog
These dialogs provide some fairly sophisticated features for you automatically with no additional code. For example, the OpenFileDialog
class lets the user browse through the filesystem to select a file to open. The dialog can automatically verify that the file actually exists so the user cannot type in the name of a non-existent file and click Open.
Similarly, the SaveFileDialog
class automatically prompts the user if the selected file does exist. For example, if the user selects the existing file Test.txt
, the dialog displays the message “Test.txt already exists. Do you want to replace it?” If the user doesn't click Yes, the dialog doesn't close. By the time the dialog closes, the user must have picked a file that doesn't yet exist or signed off on destroying the original file.
In this lesson you learn how to display these standard dialogs. You learn how to initialize them to show the user the program's current settings, how to tell which button the user clicked, and how to use the selections the user made.
You can use all of the standard dialogs in more or less the same way. The only differences are in how you initialize the dialogs so they show colors, fonts, files, or whatever and in how you handle the results.
You can use a standard dialog in Windows Forms applications by following these four steps:
You can add a dialog to a form just as you add any other component, such as a Timer
. Like other components, the dialog appears below the form in the Component Tray.
The control Toolbox has a Dialogs tab that contains most of the standard dialogs so they are easy to find. The printing-related dialogs are contained in the Printing tab so they're also easy to find (if you know to look there). Figure 8.1 shows the Toolbox's Printing and Dialogs tabs.
Most of the standard dialogs start with some initial selection. The FontDialog
starts with a font selected, the ColorDialog
starts with a color selected, and so forth. Normally you should initialize the dialog so it shows the user your program's current settings. For example, a FontDialog
should show the program's current font.
Usually making these initial selections is easy. Simply set the dialog's key property (Font
, Color
, Filename
) to the value you want to display.
For example, the following code sets a ColorDialog
's Color
property to the form's current BackColor
value. (Recall that this
means the form or other object that is currently executing the code.)
backgroundColorDialog.Color = this.BackColor;
The only real trick here is in knowing what properties to set. Table 8.1 lists the key properties for the different kinds of dialogs.
Dialog | Key Property |
ColorDialog |
Color |
FolderBrowserDialog |
SelectedPath |
FontDialog |
Font |
OpenFileDialog |
FileName |
SaveFileDialog |
FileName |
The PageSetupDialog
, PrintDialog
, and PrintPreviewDialog
are a bit different from the others so I won't say anything more about them here. Printing is covered in more detail in Lesson 30.
I just said that you should initialize the dialogs to show current values, but the file open and save dialogs have a special feature that might make you decide to skip this step. When you use them, they remember the directories they displayed last. That means if the user opens one of these dialogs again, it starts in the same directory it was in last time. In fact, if the user closes and restarts the program, the dialogs still remember where they were last.
The only reason you might want to initialize these dialogs is if you want the program to separately track more than one file. For example, you might want different places to save text files, bitmaps, and RTF files.
Also note that the OpenFileDialog
and SaveFileDialog
remember the same directory, so if you want to be able to load from one directory and save into another, you might want to initialize the dialogs.
You display all of the standard dialogs by calling their ShowDialog
methods. ShowDialog
displays the dialog modally and then returns a value to tell the program whether the user clicked OK, Cancel, or some other button.
Your code should test the returned result and, if the user clicked OK, it should do something with the user's selection.
Unfortunately to make that test, you need to use an if
statement, and if
statements aren't covered until Lesson 18. Luckily this particular use of if
statements is quite simple, so I feel only a little guilty about showing it to you now.
The following code shows how a program can display a ColorDialog
named backgroundColorDialog
:
if (backgroundColorDialog.ShowDialog() == DialogResult.OK)
{
...
}
The code calls the dialog's ShowDialog
method. It then uses the if
statement to compare the value that ShowDialog
returns to the value DialogResult.OK
. If the values are equal (that's what ==
means in C#), the program does whatever is inside the braces (which I've omitted here).
If the user clicks the Cancel button, ShowDialog
returns the value DialogResult.Cancel
, so the if
test fails and the program skips the code inside the braces.
Finally, if the user clicked OK, the program should do something with whatever the user selected in the dialog. Often this means doing the opposite of the step where you initialized the dialog. For example, suppose a program uses the following code to initialize its ColorDialog
:
backgroundColorDialog.Color = this.BackColor;
Then it would use the following code to set the form's BackColor
property to the color that the user selected:
this.BackColor = backgroundColorDialog.Color;
The following code shows the whole sequence for a ColorDialog
. The program initializes the dialog, displays it and checks the return value, and processes the result:
backgroundColorDialog.Color = this.BackColor;
if (backgroundColorDialog.ShowDialog() == DialogResult.OK)
{
this.BackColor = backgroundColorDialog.Color;
}
This looks a bit more complicated than code examples in previous lessons, but it's not too bad. The only new part is the if
test. The other statements simply set the dialog's Color
property equal to the form's BackColor
property and vice versa, and you've been setting properties for quite a while now.
Table 8.1 earlier in this lesson listed the dialogs' key properties, but some of the dialogs have other useful properties, too.
For example, the ColorDialog
has an AllowFullOpen
property that determines whether the user can click the dialog's Define Custom Colors button to show an area on the right where the user can create new colors. Figure 8.2 shows a ColorDialog
displaying this area.
You can learn more about these extra properties by reading the online help. For example, Microsoft's help page for the ColorDialog
is msdn.microsoft.com/library/system.windows.forms.colordialog.aspx
. You can replace colordialog
in this URL with the name of another dialog to find its web page.
Table 8.2 summarizes the ColorDialog
's most useful properties.
Property | Purpose |
AllowFullOpen |
Determines whether the user can create custom colors. |
Color |
The selected color. |
FullOpen |
Determines whether the custom color area is open when the dialog appears. |
Table 8.3 summarizes the FolderBrowserDialog
's most useful properties.
Property | Purpose |
RootFolder |
The root folder where the dialog starts browsing. The Properties window lets you pick from values such as Desktop , Favorites , History , and MyComputer . |
SelectedPath |
The selected folder. |
Table 8.4 summarizes the FontDialog
's most useful properties.
Property | Purpose |
FixedPitchOnly |
Determines if the dialog allows the user to select only fixed-width fonts. This is useful, for example, if you are going to use the font to build a report and you need the characters to all have the same width so columns line up properly. |
Font |
The selected font. |
FontMustExist |
Determines whether the dialog raises an error if the selected font doesn't exist (for example, if the user types “ExtraBold” for the font style and that style isn't available for the selected font). |
MaxSize |
The largest allowed size for the font. |
ShowColor |
Determines whether the dialog lets the user select a font color. If you set this to True , use the dialog's Color property to see which color was selected. |
ShowEffects |
Determines whether the dialog lets the user select underline, strikeout, and font color. (To select font color, ShowColor and ShowEffects must both be True .) |
Table 8.5 summarizes the OpenFileDialog
's most useful properties.
Property | Purpose |
AddExtension |
If this is True and the user selects a filename without an extension, the dialog adds the default extension to the name. |
CheckFileExists |
If this is True , the dialog won't let the user pick a file that doesn't exist. |
CheckPathExists |
If this is True , the dialog won't let the user pick a file path that doesn't exist. |
DefaultExt |
The default file extension. |
FileName |
The selected file's name. |
Filter |
The file selection filter. (See the section “Using File Filters” later in this lesson for details.) |
FilterIndex |
The index of the currently selected filter. (See the section “Using File Filters” later in this lesson for details.) |
InitialDirectory |
The directory where the dialog initially starts. |
ReadOnlyChecked |
Indicates whether the user checked the dialog's Read Only box. |
ShowReadOnly |
Determines whether the dialog displays its Read Only box. |
Title |
The text displayed in the dialog's title bar. |
The SaveFileDialog
has many of the same properties as the OpenFileDialog
. See Table 8.5 for descriptions of the properties AddExtension
, CheckFileExists
, CheckPathExists
, DefaultExt
, FileName
, Filter
, FilterIndex
, InitialDirectory
, and Title
.
Table 8.6 summarizes SaveFileDialog
properties that are not shared with the OpenFileDialog
.
Property | Purpose |
CreatePrompt |
If this is True , and the user selects a file that doesn't exist, the dialog asks if the user wants to create the file. |
OverwritePrompt |
If this is True and the user selects a file that already exists, the dialog asks if the user wants to overwrite it. |
ValidateNames |
Determines whether the dialog verifies that the filename doesn't contain any invalid characters. |
Table 8.7 summarizes the PrintDialog
's most useful property.
Property | Purpose |
Document |
You set this property to tell the dialog what document object to print. Lesson 30 has more to say about this. |
Table 8.8 summarizes the PrintPreviewDialog
's most useful property.
Most of the dialogs' properties are fairly easy to understand. Two properties that are particularly confusing and important, however, are the Filter
and FilterIndex
properties provided by the OpenFileDialog
and SaveFileDialog
.
The Filter
property is a list of text prompts and file-matching patterns separated by the | character. The items alternate between text prompts and the corresponding filter. The dialog provides a dropdown list where the user can select one of the text prompts. When the user selects a prompt, the dialog uses the corresponding filter to decide which files to display.
For example, consider the following value:
Bitmap Files|*.bmp|Graphic Files|*.bmp;*.gif;*.png;*.jpg|All Files|*.*
This value represents three categories of files:
*.bmp
.*.bmp;*.gif;*.png;*.jpg
. That filter matches files ending with .bmp, .gif, .png, or .jpg.*.*
.Figure 8.3 shows an OpenFileDialog
. The filter dropdown (just above the Open and Cancel buttons) has the text prompt “Graphics Files” selected. (The dialog automatically added the filter in parentheses just to confuse the user.) The dialog is listing the files in this directory that match the filter. In this case, the directory contains seven .png
files.
Once you understand the Filter
property, the FilterIndex
property is simple. FilterIndex
is simply the index of the selected filter, where 1 means the first filter, 2 means the second, and so forth. (Remember in Lesson 7 when I said, “almost all numbering starts with 0 in C#”? This is one of the rare exceptions.) You can use FilterIndex
to initially select the filter that you think will be most useful to the user.
The OpenFileDialog
and SaveFileDialog
both use the same type of Filter
and FilterIndex
properties. In fact, usually if a program displays both of these dialogs, they should use the same Filter
value. If a program can load .txt
and .rtf
files, it should probably be able to save .txt
and .rtf
files.
Unfortunately, WPF provides only a PrintDialog
and doesn't include the other standard dialogs.
If you've been paying attention, you're probably saying, “Wait. Earlier in this lesson you said that the standard dialogs were provided by the .NET Framework. Doesn't that mean WPF programs can use them, too?” (If you said this and are reading this book as part of a programming course, tell your instructor that you deserve 5 extra points on the next quiz.)
That's true—WPF programs can use the standard dialogs, but not in the same way a Windows Forms application does.
WPF normally doesn't display the common dialogs in the Toolbox, so you can't add them to a window and you can't set their properties in the Properties window at design time. Instead, you need to create, initialize, and display the dialogs with code.
Before you write any code, you need to tell Visual Studio about the part of the .NET Framework that contains the dialogs. To do that, open the Project menu and select Add Reference to open the Reference Manager shown in Figure 8.4.
On this dialog, check the boxes next to System.Windows.Forms and System.Drawing, and click OK. (The first reference tells where the dialogs are defined. The second lets the program understand Color
and Font
objects, so you need it if you're working with those two dialogs.)
Now you can use code similar to the following to make a WPF program display an OpenFileDialog
:
// Create the OpenFileDialog.
System.Windows.Forms.OpenFileDialog fileDialog =
new System.Windows.Forms.OpenFileDialog();
// Set the Filter.
fileDialog.Filter = "Text Files|*.txt|RTF Files|*.rtf|All Files|*.*";
// Display the dialog and check the result.
if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// Process the selected file.
MessageBox.Show(fileDialog.FileName);
}
The first statement (which spans two lines because it's so long) creates a System.Windows.Forms.OpenFileDialog
object. That statement really just creates an OpenFileDialog
object. The rest of the declaration tells Visual Studio that this kind of object is located in the System.Windows.Forms
part of the .NET Framework.
Next the code initializes the dialog. This example just sets the dialog's Filter
property, but you could set other properties, too, such as FilterIndex
, CheckFileExists
, and ShowReadOnly
.
The code then displays the dialog by calling its ShowDialog
method as before and compares the returned result with System.Windows.Forms.DialogResult.OK
. If the user clicked the OK button, the program processes the result. This example simply displays the selected file's name in a message box, but a real application would do something like open the file.
Unfortunately, the results returned by some of the dialogs aren't directly usable by a WPF program. For example, the ColorDialog
lets the user select a Color
but WPF programs use Brush
es instead of Color
s. Similarly, the FontDialog
lets the user pick a Font
but WPF programs don't use Font
objects directly. Some of this lesson's exercises show how you can work around some of those issues.
In this Try It, you get to try out all of the standard dialogs except the PageSetupDialog
(which is hard to use until you're doing actual printing). You initialize, display, and process the results of the dialogs (if the user clicks the OK button).
In this lesson, you:
Label
s, TextBox
es, and Button
s to make a form similar to the one shown in Figure 8.5.ColorDialog
, FontDialog
, FolderBrowserDialog
, OpenFileDialog
, SaveFileDialog
, PrintDialog
, and PrintPreviewDialog
components to the form.ColorDialog
but don't allow the user to define custom colors. If the user clicks OK, set the form's BackColor
property to the dialog's Color
value.FontDialog
, allowing the user to select the font's color. If the user clicks OK, set the form's Font
property to the dialog's Font
value and its ForeColor
property to the dialog's Color
property.FolderBrowserDialog
. Make the dialog start browsing at MyComputer. If the user clicks OK, make the Folder TextBox
display the dialog's SelectedPath
property.OpenFileDialog
. Use a filter that lets the user select text files, RTF files, or all files. If the user clicks Open, make the Open File TextBox
display the dialog's FileName
property and set the SaveFileDialog
's FilterIndex
equal to the OpenFileDialog
's FilterIndex
.SaveFileDialog
. Use the same filter used by the OpenFileDialog
. If the user clicks Save, make the Save File TextBox
display the dialog's FileName
property and set the OpenFileDialog
's FilterIndex
equal to the SaveFileDialog
's FilterIndex
.PrintDialog
and ignore the return result.PrintPreviewDialog
and ignore the return result.Label
s, TextBox
es, and Button
s to make a form similar to the one shown in Figure 8.5.
Button
s' Anchor
properties to Top, Right
. Set the TextBox
es' Anchor
properties to Top, Left, Right
.ColorDialog
, FontDialog
, FolderBrowserDialog
, OpenFileDialog
, SaveFileDialog
, PrintDialog
, and PrintPreviewDialog
components to the form.
ColorDialog
but don't allow the user to define custom colors. If the user clicks OK, set the form's BackColor
property to the dialog's Color
value.
ColorDialog
's AllowFullOpen
property to False
.private void backColorButton_Click(object sender, EventArgs e)
{
backgroundColorDialog.Color = BackColor;
if (backgroundColorDialog.ShowDialog() == DialogResult.OK)
{
BackColor = backgroundColorDialog.Color;
}
}
FontDialog
, allowing the user to select the font's color. If the user clicks OK, set the form's Font
property to the dialog's Font
value and its ForeColor
property to the dialog's Color
property.
ShowColor
property to True
.private void fontButton_Click(object sender, EventArgs e)
{
formFontDialog.Font = Font;
formFontDialog.Color = ForeColor;
if (formFontDialog.ShowDialog() == DialogResult.OK)
{
Font = formFontDialog.Font;
fontTextBox.Text = formFontDialog.Font.ToString();
ForeColor = formFontDialog.Color;
}
}
FolderBrowserDialog
. Make the dialog start browsing at MyComputer. If the user clicks OK, make the Folder TextBox
display the dialog's SelectedPath
property.
RootFolder
property to MyComputer
.private void folderButton_Click(object sender, EventArgs e)
{
if (testFolderBrowserDialog.ShowDialog() == DialogResult.OK)
{
folderTextBox.Text = testFolderBrowserDialog.SelectedPath;
}
}
OpenFileDialog
. Use a filter that lets the user select text files, RTF files, or all files. If the user clicks Open, make the Open File TextBox
display the dialog's FileName
property and set the SaveFileDialog
's FilterIndex
equal to the OpenFileDialog
's FilterIndex
.
Text Files|*.txt|RTF Files|*.rtf|All Files|*.*
private void openFileButton_Click(object sender, EventArgs e)
{
if (testOpenFileDialog.ShowDialog() == DialogResult.OK)
{
openFileTextBox.Text = testOpenFileDialog.FileName;
testSaveFileDialog.FilterIndex =
testOpenFileDialog.FilterIndex;
}
}
SaveFileDialog
. Use the same filter used by the OpenFileDialog
. If the user clicks Save, make the Save File TextBox
display the dialog's FileName
property and set the OpenFileDialog
's FilterIndex
equal to the SaveFileDialog
's FilterIndex
.
Text Files|*.txt|RTF Files|*.rtf|All Files|*.*
private void saveFileButton_Click(object sender, EventArgs e)
{
if (testSaveFileDialog.ShowDialog() == DialogResult.OK)
{
saveFileTextBox.Text = testSaveFileDialog.FileName;
testOpenFileDialog.FilterIndex =
testSaveFileDialog.FilterIndex;
}
}
PrintDialog
. Ignore the return result.
private void printButton_Click(object sender, EventArgs e)
{
testPrintDialog.ShowDialog();
}
PrintPreviewDialog
. Ignore the return result.
private void printPreviewButton_Click(object sender, EventArgs e)
{
testPrintPreviewDialog.ShowDialog();
}
ColorDialog
or FontDialog
, just display the user's selections in TextBox
es. For the ColorDialog
, display the dialog's Color.ToString()
value. For the FontDialog
, display the dialog's Font.ToString()
value. (Hint: Don't worry about setting the dialogs' FilterIndex
properties.)Color backColor = new Color()
{
A = 255,
R = colorDialog.Color.R,
G = colorDialog.Color.G,
B = colorDialog.Color.B
};
Background = new SolidColorBrush(backColor);
For the font color, use a similar technique to set the foreground color of the font TextBox
. (Setting the foreground color for the entire window is harder.)
Hints:
if (!IsLoaded) return;
RadioButton
s' Checked
events, use code similar to the following:
sampleLabel.FontFamily = new FontFamily("Arial");
Slider
's ValueChanged
event, use code similar to the following:
if (!IsLoaded) return;
sizeGroupBox.Header = "Size: " + sizeSlider.Value.ToString();
sampleLabel.FontSize = sizeSlider.Value;
Checked
and Unchecked
event handlers to the Bold CheckBox
. Make them set sampleLabel.FontWeight
to FontWeights.Bold
or FontWeights.Normal
.Checked
event handlers to the Normal, Italic, and Oblique RadioButton
s. Make them set sampleLabel.FontStyle
to FontStyles.Normal
, FontStyles.Italic
, and FontStyles.Oblique,
respectively.Filter
properties that let the user select RTF files, text files, or all files. Continue using the RichTextBox
's LoadFile
and SaveFile
methods even though they don't work properly for non-RTF files.RichTextBox
's selected text use the selected font.18.220.245.140