using Microsoft.Win32; namespace Melskin.Controls; /// /// ChooseBox 控件继承自 TextBox,用于提供一个带有选择按钮的文本框。该控件主要用于文件或文件夹的选择,并且可以设置占位符文本、选择类型等属性。 /// public class ChooseBox : System.Windows.Controls.TextBox { private Button? PART_ChooseButton; static ChooseBox() { DefaultStyleKeyProperty.OverrideMetadata(typeof(ChooseBox), new FrameworkPropertyMetadata(typeof(ChooseBox))); } /// /// 获取或设置控件中的占位符文本。 /// public string PlaceholderText { get => (string)GetValue(PlaceholderTextProperty); set => SetValue(PlaceholderTextProperty, value); } /// /// 获取或设置占位符文本的依赖属性。 /// public static readonly DependencyProperty PlaceholderTextProperty = DependencyProperty.Register(nameof(PlaceholderText), typeof(string), typeof(ChooseBox), new PropertyMetadata(string.Empty)); #region Event Implement Function private void PART_ChooseButton_Click(object sender, RoutedEventArgs e) { switch (ChooseType) { case ChooseType.SingleFile: OpenFileDialog openFileDialog = new() { Multiselect = false, //"文本文件|*.*|C#文件|*.cs|所有文件|*.*" Filter = Filter }; if (openFileDialog.ShowDialog() == true) this.Text = openFileDialog.FileName; break; case ChooseType.MultiFiles: OpenFileDialog multiFileDialog = new() { Multiselect = true, Filter = Filter }; if (multiFileDialog.ShowDialog() == true) { var fileName = string.Empty; foreach (var item in multiFileDialog.FileNames) { fileName += $"{item};"; } this.Text = fileName.TrimEnd(';'); } break; case ChooseType.Folder: var folderDialog = new VistaFolderBrowserDialog(); if (folderDialog.ShowDialog() == true) this.Text = folderDialog.SelectedPath; break; case ChooseType.SaveFile: var fileDialog = new SaveFileDialog { Filter = Filter, //设置文件类型 FileName = DefaultFileName, //设置默认文件名 DefaultExt = DefaultExt, //设置默认格式(可以不设) AddExtension = true //设置自动在文件名中添加扩展名 }; if (fileDialog.ShowDialog() == true) this.Text = fileDialog.FileName; break; } } #endregion #region Override /// public override void OnApplyTemplate() { base.OnApplyTemplate(); PART_ChooseButton = this.GetTemplateChild("PART_ChooseButton") as System.Windows.Controls.Button; if (PART_ChooseButton != null) { PART_ChooseButton.Click += PART_ChooseButton_Click; } } #endregion #region ChooseButtonStyle /// /// 获取或者设置选择按钮的样式 /// public Style ChooseButtonStyle { get => (Style)GetValue(ChooseButtonStyleProperty); set => SetValue(ChooseButtonStyleProperty, value); } /// /// 获取或设置选择按钮的样式。 /// public static readonly DependencyProperty ChooseButtonStyleProperty = DependencyProperty.Register( nameof(ChooseButtonStyle), typeof(Style), typeof(ChooseBox)); #endregion #region ChooseBoxType /// /// 获取或设置选择框的选择类型,用于指定用户可以选择单个文件、多个文件、文件夹或保存文件。 /// public ChooseType ChooseType { get => (ChooseType)GetValue(ChooseTypeProperty); set => SetValue(ChooseTypeProperty, value); } /// /// 获取或设置选择框的选择类型,用于指定用户可以选择单个文件、多个文件、文件夹还是保存文件。 /// public static readonly DependencyProperty ChooseTypeProperty = DependencyProperty.Register( nameof(ChooseType), typeof(ChooseType), typeof(ChooseBox), new PropertyMetadata(ChooseType.SingleFile, OnChooseTypeChanged)); private static void OnChooseTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not ChooseBox chooseBox) return; switch ((ChooseType)e.NewValue) { case ChooseType.SingleFile: chooseBox.PlaceholderText = "请选择文件"; break; case ChooseType.MultiFiles: chooseBox.PlaceholderText = "请选择多个文件"; break; case ChooseType.Folder: chooseBox.PlaceholderText = "请选择文件夹"; break; case ChooseType.SaveFile: chooseBox.PlaceholderText = "请选择保存文件路径"; break; default: throw new ArgumentOutOfRangeException(); } } #endregion #region ChooseButtonWidth /// /// 获取或设置选择按钮的宽度。 /// public double ChooseButtonWidth { get => (double)GetValue(ChooseButtonWidthProperty); set => SetValue(ChooseButtonWidthProperty, value); } /// /// 获取或设置选择按钮的宽度。 /// public static readonly DependencyProperty ChooseButtonWidthProperty = DependencyProperty.Register( nameof(ChooseButtonWidth), typeof(double), typeof(ChooseBox), new PropertyMetadata(24d)); #endregion #region ChooseBoxFilter /// /// 获取或设置文件对话框中使用的过滤器,用于指定可选择的文件类型。 /// public string Filter { get => (string)GetValue(FilterProperty); set => SetValue(FilterProperty, value); } /// /// 获取或设置文件过滤器,用于指定在选择文件时显示的文件类型。 /// public static readonly DependencyProperty FilterProperty = DependencyProperty.Register( nameof(Filter), typeof(string), typeof(ChooseBox), new PropertyMetadata("所有文件|*.*")); #endregion #region DefaultFileName /// /// 获取或设置保存文件对话框中的默认文件名。 /// public string DefaultFileName { get => (string)GetValue(DefaultFileNameProperty); set => SetValue(DefaultFileNameProperty, value); } /// /// 获取或设置选择框的默认文件名。 /// public static readonly DependencyProperty DefaultFileNameProperty = DependencyProperty.Register( nameof(DefaultFileName), typeof(string), typeof(ChooseBox), new PropertyMetadata("文件")); #endregion #region DefaultExt /// /// 获取或设置文件对话框中的默认扩展名。 /// public string DefaultExt { get => (string)GetValue(DefaultExtProperty); set => SetValue(DefaultExtProperty, value); } /// /// 获取或设置默认的文件扩展名。 /// public static readonly DependencyProperty DefaultExtProperty = DependencyProperty.Register( nameof(DefaultExt), typeof(string), typeof(ChooseBox), new PropertyMetadata(string.Empty)); #endregion } /// /// 定义选择框的选择类型。 /// public enum ChooseType { /// /// 选择单个文件。当设置为该选项时,将打开一个文件对话框允许用户选择单个文件。 /// SingleFile, /// /// 表示选择类型为多文件。当设置此选项时,用户可以选择多个文件。 /// MultiFiles, /// /// 表示选择类型为文件夹。当设置此选项时,用户将能够通过对话框选择一个文件夹路径。 /// Folder, /// /// 选择类型为保存文件。当此枚举成员被选中时,将显示一个“另存为”对话框,允许用户选择文件的保存位置和名称。 /// SaveFile, }