using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace WxOrder.Framework.Commons; public enum InputType { Text, // 任意文本 Integer, // 整数 Decimal // 小数 } /// /// InputDialog.xaml 的交互逻辑 /// public partial class InputDialog : Window { private readonly InputType _type; private readonly bool _allowEmpty; // 输入过程中允许的"部分输入"格式(如 "-"、"1." 也允许) private static readonly Regex IntPartial = new(@"^-?\d*$"); private static readonly Regex DecPartial = new(@"^-?\d*\.?\d*$"); /// 用户输入的原始文本 public string ResultText { get; private set; } = ""; private InputDialog(Window? owner, string title, string prompt, string defaultValue, InputType type, bool allowEmpty) { InitializeComponent(); Owner = owner ?? Application.Current.Windows .OfType() .FirstOrDefault(w => w.IsActive) ?? Application.Current.MainWindow; if (Owner == null) WindowStartupLocation = WindowStartupLocation.CenterScreen; Title = title; PromptText.Text = prompt; InputBox.Text = defaultValue; _type = type; _allowEmpty = allowEmpty; // 粘贴时同样校验 DataObject.AddPastingHandler(InputBox, (s, e) => { if (_type == InputType.Text) return; if (e.DataObject.GetData(DataFormats.Text) is not string pasted || !IsPartialValid(Preview(pasted))) e.CancelCommand(); }); } private void Window_ContentRendered(object? sender, EventArgs e) { InputBox.Focus(); InputBox.SelectAll(); } // 按键输入时实时限制字符 private void InputBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e) { if (_type == InputType.Text) return; e.Handled = !IsPartialValid(Preview(e.Text)); } // 计算输入/粘贴后的文本 private string Preview(string incoming) { var t = InputBox.Text; return t.Remove(InputBox.SelectionStart, InputBox.SelectionLength) .Insert(InputBox.SelectionStart, incoming); } private bool IsPartialValid(string text) => _type switch { InputType.Integer => IntPartial.IsMatch(text), InputType.Decimal => DecPartial.IsMatch(text), _ => true }; private void Ok_Click(object sender, RoutedEventArgs e) { var text = InputBox.Text.Trim(); if (text.Length == 0 && !_allowEmpty) { ShowError("内容不能为空"); return; } if (text.Length > 0) { if (_type == InputType.Integer && !int.TryParse(text, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out _)) { ShowError("请输入有效的整数"); return; } if (_type == InputType.Decimal && !double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out _)) { ShowError("请输入有效的数字"); return; } } ResultText = text; DialogResult = true; } private void ShowError(string msg) { ErrorText.Text = msg; ErrorText.Visibility = Visibility.Visible; InputBox.Focus(); InputBox.SelectAll(); } // ================= 静态帮助方法 ================= /// 输入文本。取消返回 null。 public static string? ShowText(string prompt, string title = "输入", string defaultValue = "", bool allowEmpty = false, Window? owner = null) { var dlg = new InputDialog(owner, title, prompt, defaultValue, InputType.Text, allowEmpty); return dlg.ShowDialog() == true ? dlg.ResultText : null; } /// 输入整数。取消返回 null。 public static int? ShowInt(string prompt, string title = "输入", int? defaultValue = null, Window? owner = null) { var dlg = new InputDialog(owner, title, prompt, defaultValue?.ToString(CultureInfo.InvariantCulture) ?? "", InputType.Integer, false); return dlg.ShowDialog() == true ? int.Parse(dlg.ResultText, CultureInfo.InvariantCulture) : null; } /// 输入小数。取消返回 null。 public static double? ShowDouble(string prompt, string title = "输入", double? defaultValue = null, Window? owner = null) { var dlg = new InputDialog(owner, title, prompt, defaultValue?.ToString(CultureInfo.InvariantCulture) ?? "", InputType.Decimal, false); return dlg.ShowDialog() == true ? double.Parse(dlg.ResultText, CultureInfo.InvariantCulture) : null; } }