From 9793d879ba9e2bd485ed3d21ac060fca738ce611 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 19 Nov 2025 11:04:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E8=A1=A8=E5=8D=95=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/NavigationService.cs | 7 + .../Converters/StringConverters.cs | 55 +++ .../Extensions/ServiceCollectionExtensions.cs | 1 + .../Services/PageViewModelFactory.cs | 1 + .../ViewModels/Pages/FormPageViewModel.cs | 458 ++++++++++++++++++ .../Views/Pages/FormPageView.axaml | 389 +++++++++++++++ .../Views/Pages/FormPageView.axaml.cs | 22 + modify.md | 151 +++++- 8 files changed, 1079 insertions(+), 5 deletions(-) create mode 100644 AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs create mode 100644 AuroraDesk.Presentation/Views/Pages/FormPageView.axaml create mode 100644 AuroraDesk.Presentation/Views/Pages/FormPageView.axaml.cs diff --git a/AuroraDesk.Infrastructure/Services/NavigationService.cs b/AuroraDesk.Infrastructure/Services/NavigationService.cs index d8f29eb..b269494 100644 --- a/AuroraDesk.Infrastructure/Services/NavigationService.cs +++ b/AuroraDesk.Infrastructure/Services/NavigationService.cs @@ -253,6 +253,13 @@ public class NavigationService : INavigationService ViewModel = _pageViewModelFactory.CreatePageViewModel("livecharts2", screen) } } + }, + new NavigationItem + { + Id = "form", + Title = "表单示例", + IconType = IconType.DocumentText, + ViewModel = _pageViewModelFactory.CreatePageViewModel("form", screen) } }; diff --git a/AuroraDesk.Presentation/Converters/StringConverters.cs b/AuroraDesk.Presentation/Converters/StringConverters.cs index 4c19eb6..5a528cf 100644 --- a/AuroraDesk.Presentation/Converters/StringConverters.cs +++ b/AuroraDesk.Presentation/Converters/StringConverters.cs @@ -45,6 +45,16 @@ public static class StringConverters /// 整数到可见性的转换器(0 则不可见) /// public static readonly IValueConverter IntToVisibilityConverter = new IntToVisibilityConverter(); + + /// + /// 字符串非空检查转换器(非空则返回 true) + /// + public static readonly IValueConverter IsNotNullOrEmptyConverter = new IsNotNullOrEmptyConverter(); + + /// + /// 布尔值到可见性转换器 + /// + public static readonly IValueConverter BoolToVisibilityConverter = new BoolToVisibilityConverter(); } /// @@ -212,3 +222,48 @@ public class IntToVisibilityConverter : IValueConverter throw new NotImplementedException(); } } + +/// +/// 字符串非空检查转换器(非空则返回 true) +/// +public class IsNotNullOrEmptyConverter : IValueConverter +{ + public static IsNotNullOrEmptyConverter Instance { get; } = new(); + + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + return !string.IsNullOrEmpty(value?.ToString()); + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} + +/// +/// 布尔值到可见性转换器 +/// +public class BoolToVisibilityConverter : IValueConverter +{ + public static BoolToVisibilityConverter Instance { get; } = new(); + + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is bool boolValue) + { + // 如果 parameter 是 "Invert",则反转布尔值 + if (parameter?.ToString() == "Invert") + { + return !boolValue; + } + return boolValue; + } + return false; + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} diff --git a/AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs b/AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs index f2252b1..abb474e 100644 --- a/AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs +++ b/AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs @@ -55,6 +55,7 @@ public static class ServiceCollectionExtensions services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); // 注意:MainWindowViewModel 的注册移到主项目的 App.axaml.cs 中 // 因为它依赖 AppViewModel,而 AppViewModel 在 AddReactiveUI() 中注册 diff --git a/AuroraDesk.Presentation/Services/PageViewModelFactory.cs b/AuroraDesk.Presentation/Services/PageViewModelFactory.cs index 0c179a1..d3eaa51 100644 --- a/AuroraDesk.Presentation/Services/PageViewModelFactory.cs +++ b/AuroraDesk.Presentation/Services/PageViewModelFactory.cs @@ -66,6 +66,7 @@ public class PageViewModelFactory : IPageViewModelFactory "wireless-adapter" => CreateWirelessAdapterPageViewModel(screen), "scottplot" => CreatePageViewModel(screen), "livecharts2" => CreatePageViewModel(screen), + "form" => CreatePageViewModel(screen), _ => throw new ArgumentException($"Unknown page: {pageId}", nameof(pageId)) }; } diff --git a/AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs b/AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs new file mode 100644 index 0000000..68c14f2 --- /dev/null +++ b/AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs @@ -0,0 +1,458 @@ +using AuroraDesk.Presentation.ViewModels.Base; +using ReactiveUI; +using System.Collections.ObjectModel; +using System.Reactive; + +namespace AuroraDesk.Presentation.ViewModels.Pages; + +/// +/// 表单类型枚举 +/// +public enum FormType +{ + Basic, // 基础表单(垂直布局,全字段) + Simple, // 简洁表单(水平布局,标签和输入框一行) + Contact, // 联系表单(包含下拉框选择) + Feedback, // 反馈表单(包含复选框) + Register // 注册表单(两列布局) +} + +/// +/// 表单页面 ViewModel +/// +public class FormPageViewModel : RoutableViewModel +{ + private bool _isFormDialogOpen; + private FormType _currentFormType = FormType.Basic; + private string _formTitle = "填写表单"; + private string _formDescription = "请填写以下信息"; + private string _name = string.Empty; + private string _email = string.Empty; + private string _phone = string.Empty; + private string _address = string.Empty; + private string _remarks = string.Empty; + private string _submitResult = string.Empty; + private string _selectedCountry = string.Empty; + private string _selectedCity = string.Empty; + private bool _agreeTerms = false; + private bool _subscribeNewsletter = false; + private bool _receiveNotifications = false; + + /// + /// 构造函数 + /// + /// 宿主 Screen + public FormPageViewModel(IScreen hostScreen) : base(hostScreen, "Form") + { + // 初始化下拉框选项 + Countries = new ObservableCollection { "中国", "美国", "日本", "韩国", "英国", "德国", "法国", "其他" }; + Cities = new ObservableCollection { "北京", "上海", "广州", "深圳", "杭州", "成都", "其他" }; + + ShowBasicFormCommand = ReactiveCommand.Create(() => ShowForm(FormType.Basic)); + ShowSimpleFormCommand = ReactiveCommand.Create(() => ShowForm(FormType.Simple)); + ShowContactFormCommand = ReactiveCommand.Create(() => ShowForm(FormType.Contact)); + ShowFeedbackFormCommand = ReactiveCommand.Create(() => ShowForm(FormType.Feedback)); + ShowRegisterFormCommand = ReactiveCommand.Create(() => ShowForm(FormType.Register)); + SubmitFormCommand = ReactiveCommand.Create(SubmitForm); + CancelFormCommand = ReactiveCommand.Create(CancelForm); + } + + /// + /// 是否显示表单对话框 + /// + public bool IsFormDialogOpen + { + get => _isFormDialogOpen; + set => this.RaiseAndSetIfChanged(ref _isFormDialogOpen, value); + } + + /// + /// 当前表单类型 + /// + public FormType CurrentFormType + { + get => _currentFormType; + set => this.RaiseAndSetIfChanged(ref _currentFormType, value); + } + + /// + /// 表单标题 + /// + public string FormTitle + { + get => _formTitle; + set => this.RaiseAndSetIfChanged(ref _formTitle, value); + } + + /// + /// 表单描述 + /// + public string FormDescription + { + get => _formDescription; + set => this.RaiseAndSetIfChanged(ref _formDescription, value); + } + + /// + /// 是否显示电话字段 + /// + public bool ShowPhoneField => CurrentFormType == FormType.Basic || + CurrentFormType == FormType.Contact || + CurrentFormType == FormType.Register; + + /// + /// 是否显示地址字段 + /// + public bool ShowAddressField => CurrentFormType == FormType.Basic || + CurrentFormType == FormType.Register; + + /// + /// 是否显示备注字段 + /// + public bool ShowRemarksField => CurrentFormType == FormType.Basic || + CurrentFormType == FormType.Feedback; + + /// + /// 是否使用水平布局(标签和输入框在一行) + /// + public bool UseHorizontalLayout => CurrentFormType == FormType.Simple; + + /// + /// 是否使用两列布局 + /// + public bool UseTwoColumnLayout => CurrentFormType == FormType.Register; + + /// + /// 是否显示下拉框字段 + /// + public bool ShowComboBoxFields => CurrentFormType == FormType.Contact; + + /// + /// 是否显示复选框字段 + /// + public bool ShowCheckBoxFields => CurrentFormType == FormType.Feedback; + + /// + /// 国家列表 + /// + public ObservableCollection Countries { get; } + + /// + /// 城市列表 + /// + public ObservableCollection Cities { get; } + + /// + /// 选中的国家 + /// + public string SelectedCountry + { + get => _selectedCountry; + set => this.RaiseAndSetIfChanged(ref _selectedCountry, value); + } + + /// + /// 选中的城市 + /// + public string SelectedCity + { + get => _selectedCity; + set => this.RaiseAndSetIfChanged(ref _selectedCity, value); + } + + /// + /// 同意条款 + /// + public bool AgreeTerms + { + get => _agreeTerms; + set => this.RaiseAndSetIfChanged(ref _agreeTerms, value); + } + + /// + /// 订阅 newsletter + /// + public bool SubscribeNewsletter + { + get => _subscribeNewsletter; + set => this.RaiseAndSetIfChanged(ref _subscribeNewsletter, value); + } + + /// + /// 接收通知 + /// + public bool ReceiveNotifications + { + get => _receiveNotifications; + set => this.RaiseAndSetIfChanged(ref _receiveNotifications, value); + } + + /// + /// 姓名 + /// + public string Name + { + get => _name; + set => this.RaiseAndSetIfChanged(ref _name, value); + } + + /// + /// 邮箱 + /// + public string Email + { + get => _email; + set => this.RaiseAndSetIfChanged(ref _email, value); + } + + /// + /// 电话 + /// + public string Phone + { + get => _phone; + set => this.RaiseAndSetIfChanged(ref _phone, value); + } + + /// + /// 地址 + /// + public string Address + { + get => _address; + set => this.RaiseAndSetIfChanged(ref _address, value); + } + + /// + /// 备注 + /// + public string Remarks + { + get => _remarks; + set => this.RaiseAndSetIfChanged(ref _remarks, value); + } + + /// + /// 提交结果 + /// + public string SubmitResult + { + get => _submitResult; + set => this.RaiseAndSetIfChanged(ref _submitResult, value); + } + + /// + /// 显示基础表单命令 + /// + public ReactiveCommand ShowBasicFormCommand { get; } + + /// + /// 显示简洁表单命令 + /// + public ReactiveCommand ShowSimpleFormCommand { get; } + + /// + /// 显示联系表单命令 + /// + public ReactiveCommand ShowContactFormCommand { get; } + + /// + /// 显示反馈表单命令 + /// + public ReactiveCommand ShowFeedbackFormCommand { get; } + + /// + /// 显示注册表单命令 + /// + public ReactiveCommand ShowRegisterFormCommand { get; } + + /// + /// 提交表单命令 + /// + public ReactiveCommand SubmitFormCommand { get; } + + /// + /// 取消表单命令 + /// + public ReactiveCommand CancelFormCommand { get; } + + private void ShowForm(FormType formType) + { + // 重置表单数据 + Name = string.Empty; + Email = string.Empty; + Phone = string.Empty; + Address = string.Empty; + Remarks = string.Empty; + SelectedCountry = string.Empty; + SelectedCity = string.Empty; + AgreeTerms = false; + SubscribeNewsletter = false; + ReceiveNotifications = false; + SubmitResult = string.Empty; + + // 设置表单类型 + CurrentFormType = formType; + + // 根据表单类型设置标题和描述 + switch (formType) + { + case FormType.Basic: + FormTitle = "基础表单"; + FormDescription = "垂直布局,标签在上输入框在下"; + break; + case FormType.Simple: + FormTitle = "简洁表单"; + FormDescription = "水平布局,标签和输入框在同一行"; + break; + case FormType.Contact: + FormTitle = "联系表单"; + FormDescription = "包含下拉框选择国家/城市"; + break; + case FormType.Feedback: + FormTitle = "反馈表单"; + FormDescription = "包含复选框选项"; + break; + case FormType.Register: + FormTitle = "注册表单"; + FormDescription = "两列布局,充分利用空间"; + break; + } + + // 触发所有属性更新 + this.RaisePropertyChanged(nameof(ShowPhoneField)); + this.RaisePropertyChanged(nameof(ShowAddressField)); + this.RaisePropertyChanged(nameof(ShowRemarksField)); + this.RaisePropertyChanged(nameof(UseHorizontalLayout)); + this.RaisePropertyChanged(nameof(UseTwoColumnLayout)); + this.RaisePropertyChanged(nameof(ShowComboBoxFields)); + this.RaisePropertyChanged(nameof(ShowCheckBoxFields)); + + // 显示对话框 + IsFormDialogOpen = true; + } + + private void SubmitForm() + { + // 验证必填字段 + if (string.IsNullOrWhiteSpace(Name)) + { + SubmitResult = "错误:姓名不能为空"; + return; + } + + if (string.IsNullOrWhiteSpace(Email)) + { + SubmitResult = "错误:邮箱不能为空"; + return; + } + + // 简单的邮箱格式验证 + if (!Email.Contains("@") || !Email.Contains(".")) + { + SubmitResult = "错误:邮箱格式不正确"; + return; + } + + // 根据表单类型验证特定字段 + if (CurrentFormType == FormType.Contact || CurrentFormType == FormType.Register) + { + if (string.IsNullOrWhiteSpace(Phone)) + { + SubmitResult = "错误:电话不能为空"; + return; + } + } + + if (CurrentFormType == FormType.Register) + { + if (string.IsNullOrWhiteSpace(Address)) + { + SubmitResult = "错误:地址不能为空"; + return; + } + } + + if (CurrentFormType == FormType.Feedback) + { + if (string.IsNullOrWhiteSpace(Remarks)) + { + SubmitResult = "错误:反馈内容不能为空"; + return; + } + if (!AgreeTerms) + { + SubmitResult = "错误:必须同意服务条款"; + return; + } + } + + if (CurrentFormType == FormType.Contact) + { + if (string.IsNullOrWhiteSpace(SelectedCountry)) + { + SubmitResult = "错误:请选择国家"; + return; + } + if (string.IsNullOrWhiteSpace(SelectedCity)) + { + SubmitResult = "错误:请选择城市"; + return; + } + } + + // 关闭对话框 + IsFormDialogOpen = false; + + // 显示提交结果 + var formTypeName = CurrentFormType switch + { + FormType.Basic => "基础表单", + FormType.Simple => "简洁表单", + FormType.Contact => "联系表单", + FormType.Feedback => "反馈表单", + FormType.Register => "注册表单", + _ => "表单" + }; + + var result = $"[{formTypeName}] 提交成功!\n姓名:{Name}\n邮箱:{Email}"; + if (ShowPhoneField && !string.IsNullOrWhiteSpace(Phone)) + { + result += $"\n电话:{Phone}"; + } + if (ShowAddressField && !string.IsNullOrWhiteSpace(Address)) + { + result += $"\n地址:{Address}"; + } + if (ShowComboBoxFields) + { + if (!string.IsNullOrWhiteSpace(SelectedCountry)) + { + result += $"\n国家:{SelectedCountry}"; + } + if (!string.IsNullOrWhiteSpace(SelectedCity)) + { + result += $"\n城市:{SelectedCity}"; + } + } + if (ShowRemarksField && !string.IsNullOrWhiteSpace(Remarks)) + { + result += $"\n备注:{Remarks}"; + } + if (ShowCheckBoxFields) + { + result += $"\n同意条款:{(AgreeTerms ? "是" : "否")}"; + result += $"\n订阅邮件:{(SubscribeNewsletter ? "是" : "否")}"; + result += $"\n接收通知:{(ReceiveNotifications ? "是" : "否")}"; + } + + SubmitResult = result; + } + + private void CancelForm() + { + IsFormDialogOpen = false; + SubmitResult = "已取消提交"; + } +} + diff --git a/AuroraDesk.Presentation/Views/Pages/FormPageView.axaml b/AuroraDesk.Presentation/Views/Pages/FormPageView.axaml new file mode 100644 index 0000000..49ae09f --- /dev/null +++ b/AuroraDesk.Presentation/Views/Pages/FormPageView.axaml @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AuroraDesk.Presentation/Views/Pages/FormPageView.axaml.cs b/AuroraDesk.Presentation/Views/Pages/FormPageView.axaml.cs new file mode 100644 index 0000000..3fdbe46 --- /dev/null +++ b/AuroraDesk.Presentation/Views/Pages/FormPageView.axaml.cs @@ -0,0 +1,22 @@ +using Avalonia.Markup.Xaml; +using AuroraDesk.Presentation.ViewModels.Pages; +using ReactiveUI.Avalonia; + +namespace AuroraDesk.Presentation.Views.Pages; + +/// +/// 表单页面视图 +/// +public partial class FormPageView : ReactiveUserControl +{ + public FormPageView() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } +} + diff --git a/modify.md b/modify.md index 68054a3..85ba820 100644 --- a/modify.md +++ b/modify.md @@ -2213,8 +2213,149 @@ - 直接更新 `Values` 集合(`ObservableCollection`),实现平滑的叠加效果 - 使用 `CreateLineSeries()` 方法创建系列,`UpdateLineChartData()` 只更新数据 - 避免整个图表重新渲染,实现真正的叠加动画效果 - - **阈值颜色区分**: - - 使用 `LineSeries` 显示折线,保持点的位置关系 - - 使用 `ScatterSeries` 显示点,支持不同颜色 - - 超过阈值的点显示为绿色,正常点显示为蓝色/红色 - - 阈值改变时自动更新图表颜色 + - **阈值颜色区分**: + - 使用 `LineSeries` 显示折线,保持点的位置关系 + - 使用 `ScatterSeries` 显示点,支持不同颜色 + - 超过阈值的点显示为绿色,正常点显示为蓝色/红色 + - 阈值改变时自动更新图表颜色 + +### 新增表单示例页面 +- **日期**: 2025年1月 +- **功能描述**: 添加了表单示例页面,包含按钮点击弹出表单对话框功能 +- **实现内容**: + 1. **ViewModel 层**: + - 创建 `FormPageViewModel`,继承自 `RoutableViewModel` + - 实现表单字段属性:姓名、邮箱、电话、地址、备注 + - 实现表单对话框显示/隐藏控制:`IsFormDialogOpen` + - 提供表单提交和取消命令:`ShowFormCommand`、`SubmitFormCommand`、`CancelFormCommand` + - 实现表单验证逻辑:必填字段检查、邮箱格式验证 + - 显示提交结果信息 + 2. **View 层**: + - 创建 `FormPageView.axaml`,使用 `DialogHost` 实现弹出表单 + - 主界面包含"打开表单"按钮和结果显示区域 + - 表单对话框包含: + - 标题区域(带图标) + - 表单字段:姓名(必填)、邮箱(必填)、电话(可选)、地址(可选)、备注(可选) + - 错误提示区域(动态显示验证错误) + - 提交和取消按钮 + - 表单支持滚动,适配长内容 + 3. **转换器扩展**: + - 在 `StringConverters` 中新增 `IsNotNullOrEmptyConverter` 转换器 + - 用于检查字符串是否非空,控制错误提示区域的显示 + 4. **服务注册**: + - 在 `PageViewModelFactory` 中注册 `form` 页面 ID + - 在 `ServiceCollectionExtensions` 中注册 `FormPageViewModel` + - 在 `NavigationService` 中添加"表单示例"导航项,使用 `IconType.DocumentText` 图标 +- **涉及文件**: + - `AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs` - ViewModel + - `AuroraDesk.Presentation/Views/Pages/FormPageView.axaml` - 视图 XAML + - `AuroraDesk.Presentation/Views/Pages/FormPageView.axaml.cs` - 视图代码后台 + - `AuroraDesk.Presentation/Converters/StringConverters.cs` - 新增转换器 + - `AuroraDesk.Presentation/Services/PageViewModelFactory.cs` - 页面工厂注册 + - `AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs` - ViewModel 注册 + - `AuroraDesk.Infrastructure/Services/NavigationService.cs` - 导航服务 +- **技术特点**: + - ✅ 使用 ReactiveUI + MVVM 模式 + - ✅ 使用 DialogHost.Avalonia 实现模态对话框 + - ✅ 支持表单验证和错误提示 + - ✅ 现代化的界面设计,表单布局清晰 + - ✅ 支持必填字段和可选字段 + - ✅ 提交结果显示在主界面 +- **效果**: + - ✅ 可以在导航栏中访问"表单示例"页面 + - ✅ 点击"打开表单"按钮弹出表单对话框 + - ✅ 填写表单信息并提交,支持验证 + - ✅ 提交结果显示在主界面 + - ✅ 表单界面美观,交互流畅 + +### 扩展表单示例页面 - 支持多种表单形态 +- **日期**: 2025年1月 +- **功能描述**: 扩展表单页面,添加多个按钮,每个按钮对应不同的表单形态 +- **实现内容**: + 1. **表单类型枚举**: + - 新增 `FormType` 枚举,定义5种表单类型: + - `Basic`: 基础表单(全字段:姓名、邮箱、电话、地址、备注) + - `Simple`: 简洁表单(仅姓名、邮箱) + - `Contact`: 联系表单(姓名、电话、邮箱) + - `Feedback`: 反馈表单(姓名、邮箱、备注) + - `Register`: 注册表单(姓名、邮箱、电话、地址) + 2. **ViewModel 扩展**: + - 添加 `CurrentFormType` 属性,标识当前表单类型 + - 添加 `FormTitle` 和 `FormDescription` 属性,动态显示表单标题和描述 + - 添加字段可见性属性:`ShowPhoneField`、`ShowAddressField`、`ShowRemarksField` + - 添加5个不同的命令:`ShowBasicFormCommand`、`ShowSimpleFormCommand`、`ShowContactFormCommand`、`ShowFeedbackFormCommand`、`ShowRegisterFormCommand` + - 根据表单类型动态设置标题、描述和字段可见性 + - 根据表单类型进行不同的验证规则 + 3. **View 扩展**: + - 添加5个不同颜色的按钮,每个按钮对应一种表单类型 + - 按钮颜色区分:基础表单(蓝色)、简洁表单(绿色)、联系表单(紫色)、反馈表单(橙色)、注册表单(红色) + - 表单字段根据 `IsVisible` 绑定动态显示/隐藏 + - 表单标题和描述绑定到 ViewModel 属性,动态更新 + 4. **验证逻辑优化**: + - 基础表单:验证姓名和邮箱 + - 简洁表单:验证姓名和邮箱 + - 联系表单:验证姓名、邮箱和电话 + - 反馈表单:验证姓名、邮箱和备注 + - 注册表单:验证姓名、邮箱、电话和地址 +- **涉及文件**: + - `AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs` - 扩展 ViewModel,添加表单类型和多个命令 + - `AuroraDesk.Presentation/Views/Pages/FormPageView.axaml` - 添加多个按钮,动态显示字段 +- **技术特点**: + - ✅ 使用枚举定义表单类型,类型安全 + - ✅ 根据表单类型动态显示/隐藏字段 + - ✅ 不同表单类型使用不同的验证规则 + - ✅ 按钮使用不同颜色区分,视觉清晰 + - ✅ 表单标题和描述动态更新 +- **效果**: + - ✅ 提供5种不同的表单形态,满足不同场景需求 + - ✅ 点击不同按钮打开对应类型的表单 + - ✅ 表单字段根据类型动态显示,界面简洁 + - ✅ 每种表单类型有独立的验证规则 + - ✅ 提交结果显示表单类型,便于区分 + +### 重构表单示例页面 - 实现不同布局形态和控件类型 +- **日期**: 2025年1月 +- **功能描述**: 重构表单页面,为不同表单类型设计不同的布局形态和控件组合,使每种表单在视觉和功能上都有明显区别 +- **实现内容**: + 1. **布局形态设计**: + - **基础表单**:垂直布局(标签在上,输入框在下),包含所有字段 + - **简洁表单**:水平布局(标签和输入框在同一行,使用 Grid 两列),仅包含姓名和邮箱 + - **联系表单**:垂直布局,包含下拉框(ComboBox)选择国家和城市 + - **反馈表单**:垂直布局,包含复选框(CheckBox)选项 + - **注册表单**:两列布局(使用 Grid 两列两行),充分利用空间 + 2. **新增控件类型**: + - **下拉框(ComboBox)**:用于联系表单,选择国家和城市 + - **复选框(CheckBox)**:用于反馈表单,包含"同意条款"、"订阅邮件"、"接收通知"等选项 + 3. **ViewModel 扩展**: + - 添加布局控制属性:`UseHorizontalLayout`、`UseTwoColumnLayout` + - 添加控件显示属性:`ShowComboBoxFields`、`ShowCheckBoxFields` + - 添加下拉框数据:`Countries`、`Cities`、`SelectedCountry`、`SelectedCity` + - 添加复选框数据:`AgreeTerms`、`SubscribeNewsletter`、`ReceiveNotifications` + - 根据表单类型进行不同的验证规则(包括下拉框和复选框验证) + 4. **转换器扩展**: + - 新增 `BoolToVisibilityConverter` 转换器,支持布尔值到可见性转换 + - 支持反转参数(`ConverterParameter='Invert'`),用于条件显示 + 5. **XAML 布局重构**: + - 使用条件显示(`IsVisible` 绑定)实现不同布局 + - 基础表单:垂直 StackPanel 布局 + - 简洁表单:Grid 水平布局(标签列宽 100,输入框自适应) + - 注册表单:Grid 两列两行布局 + - 联系表单:在垂直布局中添加 ComboBox + - 反馈表单:在垂直布局中添加 CheckBox +- **涉及文件**: + - `AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs` - 扩展 ViewModel,添加布局控制和控件数据 + - `AuroraDesk.Presentation/Views/Pages/FormPageView.axaml` - 重构布局,实现不同表单形态 + - `AuroraDesk.Presentation/Converters/StringConverters.cs` - 新增 BoolToVisibilityConverter +- **技术特点**: + - ✅ 5种不同的布局形态,视觉差异明显 + - ✅ 使用 Grid 实现水平布局和两列布局 + - ✅ 使用 ComboBox 和 CheckBox 丰富表单控件类型 + - ✅ 条件显示实现布局切换,代码清晰 + - ✅ 每种表单类型有独特的布局和控件组合 +- **效果**: + - ✅ 基础表单:传统垂直布局,标签在上输入框在下 + - ✅ 简洁表单:水平布局,标签和输入框在同一行,节省空间 + - ✅ 联系表单:包含下拉框选择,交互更友好 + - ✅ 反馈表单:包含复选框选项,支持多选 + - ✅ 注册表单:两列布局,充分利用横向空间 + - ✅ 每种表单形态在视觉和功能上都有明显区别