云计算百科
云计算领域专业知识百科平台

WPF:文件/文件夹选择对话框

环境: VS2022+.Net Framework4.8
NuGet包:WindowsAPICodePack-Core 1.1.2 ;
WindowsAPICodePack-Shell 1.1.1
程序名:WpfA_OpenFileFolderDemo

一、功能概述

这是一个WPF用户控件,演示了四种不同的文件和文件夹选择对话框:

  • 打开文件对话框(OpenFileDialog):使用Win32标准对话框选择图片文件
  • 保存文件对话框(SaveFileDialog):使用Win32标准对话框保存BMP图像
  • 文件夹浏览对话框(FolderBrowserDialog):使用WinForms组件选择文件夹
  • 通用打开文件对话框(CommonOpenFileDialog):使用Windows API Code Pack选择文件夹

二、技术组件

  • FolderBrowserDialog:传统样式,使用WinForms,需要添加System.Windows.Forms引用
  • CommonOpenFileDialog:现代化Vista风格对话框,通过IsFolderPicker=true切换到文件夹选择模式,界面更美观
  • 添加引用
    右键点击项目 → 选择 “添加” → “引用”
    在引用管理器中,左侧选择 “程序集” → “框架”
    在右侧列表中,找到并勾选:
    System.Windows.Forms
    System.Drawing
    点击 “确定”

三、WindowsAPICodePack.Dialogs 属性与方法

CommonOpenFileDialog 主要属性

属性类型说明
Title string 对话框标题
IsFolderPicker bool true时选择文件夹,false时选择文件
Multiselect bool 是否允许多选
DefaultFileName string 默认文件名
InitialDirectory string 初始目录
FileName string 用户选择的文件/文件夹路径
FileNames ICollection 多选时的所有文件路径集合
Filters IList 文件类型过滤器
EnsurePathExists bool 确保路径存在
EnsureValidNames bool 确保文件名有效
EnsureReadOnly bool 确保文件为只读

常用方法

  • ShowDialog()
    显示对话框,返回CommonFileDialogResult枚举
  • ShowDialog(Window owner)
    指定所有者窗口显示
    ##CommonFileDialogResult 枚举值
  • Ok:用户点击确定
  • Cancel:用户取消

四、程序

1、MainWindow.xaml

<Window x:Class="WpfA_OpenFileFolderDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfA_OpenFileFolderDemo"
Title="文件/文件夹选择对话框演示 – .NET Framework 4.8"
Height="550"
Width="750"
WindowStartupLocation="CenterScreen"
Background="#F5F5F5">

<Window.Resources>
<!– TextBox圆角样式 –>
<Style TargetType="TextBox" x:Key="RoundedTextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4">
<ScrollViewer x:Name="PART_ContentHost"
Margin="5,2"
VerticalScrollBarVisibility="Auto"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style TargetType="Button" x:Key="DemoButton">
<Setter Property="Width" Value="380"/>
<Setter Property="Height" Value="48"/>
<Setter Property="Margin" Value="0,6"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Background" Value="#3498DB"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
CornerRadius="6"
BorderThickness="0">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="10,0"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#2980B9"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#1A5276"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style TargetType="Button" x:Key="ClearButton">
<Setter Property="Width" Value="120"/>
<Setter Property="Height" Value="30"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="Background" Value="#E74C3C"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
CornerRadius="4">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#C0392B"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#922B21"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>

<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<Border Grid.Row="0" Background="#2C3E50" CornerRadius="8" Padding="15" Margin="0,0,0,20">
<TextBlock Text="📁 文件与文件夹选择对话框演示"
FontSize="22"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
</Border>

<StackPanel Grid.Row="1" Orientation="Vertical" HorizontalAlignment="Center">
<Button Style="{StaticResource DemoButton}"
Content="📂 打开文件 (OpenFileDialog)"
Click="OpenFile_Click"
ToolTip="使用Win32标准对话框选择图片文件"/>

<Button Style="{StaticResource DemoButton}"
Content="💾 保存文件 (SaveFileDialog)"
Click="SaveFile_Click"
ToolTip="使用Win32标准对话框保存BMP图像"/>

<Button Style="{StaticResource DemoButton}"
Content="📁 打开文件夹 (FolderBrowserDialog)"
Click="FolderBrowser_Click"
ToolTip="使用WinForms组件选择文件夹 (传统样式)"/>

<Button Style="{StaticResource DemoButton}"
Content="📁 打开文件夹 (CommonOpenFileDialog)"
Click="CommonOpenFile_Click"
ToolTip="使用Windows API Code Pack选择文件夹 (Vista风格)"/>

<Button Style="{StaticResource ClearButton}"
Content="🗑️ 清空结果"
Margin="0,15,0,0"
Click="ClearResult_Click"/>
</StackPanel>

<Border Grid.Row="2"
Margin="0,20,0,0"
Padding="15"
Background="White"
BorderBrush="#BDC3C7"
BorderThickness="1"
CornerRadius="8"
Height="150">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<TextBlock Grid.Row="0"
Text="📋 选择结果:"
FontWeight="Bold"
FontSize="14"
Margin="0,0,0,8"
Foreground="#2C3E50"/>

<TextBox Grid.Row="1"
x:Name="ResultTextBox"
Style="{StaticResource RoundedTextBox}"
TextWrapping="Wrap"
AcceptsReturn="True"
VerticalScrollBarVisibility="Auto"
IsReadOnly="True"
Background="#FAFAFA"
BorderBrush="#D5D8DC"
BorderThickness="1"
FontFamily="Consolas"
FontSize="13"
Padding="8"/>
</Grid>
</Border>

<StatusBar Grid.Row="2"
VerticalAlignment="Bottom"
Height="25"
Background="#ECF0F1">
<StatusBarItem>
<TextBlock x:Name="StatusText"
Text="就绪"
FontSize="12"
Foreground="#7F8C8D"/>
</StatusBarItem>
</StatusBar>
</Grid>
</Window>

2、MainWindow.xaml.cs

using System;
using System.Windows;
using Microsoft.Win32;
using Microsoft.WindowsAPICodePack.Dialogs;

namespace WpfA_OpenFileFolderDemo
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

/// <summary>
/// 更新结果文本框和状态栏
/// </summary>
private void UpdateResult(string message, bool isSuccess = true)
{
string timestamp = DateTime.Now.ToString("HH:mm:ss");
string icon = isSuccess ? "✅" : "❌";

// 在结果框中追加内容
string newLine = $"[{timestamp}] {message}";
if (string.IsNullOrEmpty(ResultTextBox.Text))
{
ResultTextBox.Text = newLine;
}
else
{
ResultTextBox.Text += Environment.NewLine + newLine;
}

// 滚动到底部
ResultTextBox.ScrollToEnd();

// 更新状态栏
StatusText.Text = isSuccess ? $"✓ {message}" : $"✗ {message}";
StatusText.Foreground = isSuccess ?
System.Windows.Media.Brushes.Green :
System.Windows.Media.Brushes.Red;
}

/// <summary>
/// 清空结果
/// </summary>
private void ClearResult_Click(object sender, RoutedEventArgs e)
{
ResultTextBox.Clear();
StatusText.Text = "已清空";
StatusText.Foreground = System.Windows.Media.Brushes.Gray;
}

/// <summary>
/// 打开文件 – OpenFileDialog
/// </summary>
private void OpenFile_Click(object sender, RoutedEventArgs e)
{
try
{
OpenFileDialog dialog = new OpenFileDialog
{
Title = "选择图片文件",
Filter = "图像文件 (*.jpg;*.png;*.bmp;*.gif)|*.jpg;*.png;*.bmp;*.gif|所有文件 (*.*)|*.*",
RestoreDirectory = true,
Multiselect = false,
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
};

bool? result = dialog.ShowDialog();
if (result == true)
{
UpdateResult($"选择了文件:{dialog.FileName}", true);
}
else
{
UpdateResult("用户取消了操作", true);
}
}
catch (Exception ex)
{
UpdateResult($"错误:{ex.Message}", false);
}
}

/// <summary>
/// 保存文件 – SaveFileDialog
/// </summary>
private void SaveFile_Click(object sender, RoutedEventArgs e)
{
try
{
SaveFileDialog dialog = new SaveFileDialog
{
Title = "保存图像文件",
Filter = "BMP图像 (*.bmp)|*.bmp|PNG图像 (*.png)|*.png|JPEG图像 (*.jpg)|*.jpg",
RestoreDirectory = true,
FileName = $"Image_{DateTime.Now:yyyyMMdd_HHmmss}.bmp",
DefaultExt = ".bmp",
AddExtension = true,
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
};

bool? result = dialog.ShowDialog();
if (result == true)
{
UpdateResult($"保存路径:{dialog.FileName}", true);
}
else
{
UpdateResult("用户取消了操作", true);
}
}
catch (Exception ex)
{
UpdateResult($"错误:{ex.Message}", false);
}
}

/// <summary>
/// 打开文件夹 – FolderBrowserDialog (WinForms)
/// </summary>
private void FolderBrowser_Click(object sender, RoutedEventArgs e)
{
try
{
System.Windows.Forms.FolderBrowserDialog dialog =
new System.Windows.Forms.FolderBrowserDialog
{
Description = "请选择目标文件夹",
ShowNewFolderButton = true,
RootFolder = Environment.SpecialFolder.Desktop
};

// 使用WinForms的对话框
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
string foldername = dialog.SelectedPath.Trim();
UpdateResult($"选择了文件夹:{foldername}", true);
}
else
{
UpdateResult("用户取消了操作", true);
}
}
catch (Exception ex)
{
UpdateResult($"错误:{ex.Message}", false);
}
}

/// <summary>
/// 打开文件夹 – CommonOpenFileDialog (Windows API Code Pack)
/// </summary>
private void CommonOpenFile_Click(object sender, RoutedEventArgs e)
{
try
{
// 检查操作系统版本(Vista+)
if (Environment.OSVersion.Version.Major < 6)
{
UpdateResult("需要 Windows Vista 或更高版本才能使用此功能", false);
return;
}

using (CommonOpenFileDialog dialog = new CommonOpenFileDialog())
{
dialog.Title = "请选择目标文件夹 (Vista+ 风格)";
dialog.IsFolderPicker = true;
dialog.Multiselect = false;
dialog.EnsurePathExists = true;
dialog.EnsureValidNames = true;
dialog.InitialDirectory = Environment.GetFolderPath(
Environment.SpecialFolder.Desktop
);

// 显示对话框
CommonFileDialogResult result = dialog.ShowDialog();
if (result == CommonFileDialogResult.Ok)
{
string folderName = dialog.FileName;
UpdateResult($"选择了文件夹:{folderName}", true);
}
else
{
UpdateResult("用户取消了操作", true);
}
}
}
catch (Exception ex)
{
UpdateResult($"错误:{ex.Message}", false);
}
}
}
}

五、资料

【1.8 HandyControl:80余种控件使用案例】WPF案例代码解析 – 知乎](https://zhuanlan.zhihu.com/p/393756032)

赞(0)
未经允许不得转载:网硕互联帮助中心 » WPF:文件/文件夹选择对话框
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!