将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
# 通用窗体使用指南 | General Form Usage Guide
|
||||
|
||||
## 概述 | Overview
|
||||
|
||||
`XP.Common.GeneralForm` 提供 XplorePlane 项目中可复用的通用 WPF 窗体组件。当前包含以下窗体:
|
||||
|
||||
| 窗体 | 说明 |
|
||||
|---|---|
|
||||
| `ProgressWindow` | 模态进度条窗口,支持线程安全的进度更新和关闭操作 |
|
||||
| `InputDialog` | 通用输入对话框,支持单行文本输入、可选验证和多语言按钮 |
|
||||
|
||||
## 目录结构 | Directory Structure
|
||||
|
||||
```
|
||||
XP.Common/GeneralForm/
|
||||
├── ViewModels/
|
||||
│ ├── InputDialogViewModel.cs # 输入对话框 ViewModel
|
||||
│ └── ProgressWindowViewModel.cs # 进度窗口 ViewModel
|
||||
└── Views/
|
||||
├── InputDialog.xaml # 输入对话框 XAML 视图
|
||||
├── InputDialog.xaml.cs # 输入对话框 Code-Behind
|
||||
├── ProgressWindow.xaml # 进度窗口 XAML 视图
|
||||
└── ProgressWindow.xaml.cs # 进度窗口 Code-Behind
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ProgressWindow 进度条窗口
|
||||
|
||||
### 功能特性 | Features
|
||||
|
||||
- 模态进度条窗口,居中显示,不可调整大小
|
||||
- 线程安全:`UpdateProgress()` 和 `Close()` 可从任意线程调用,内部自动通过 `Dispatcher` 调度
|
||||
- 可配置是否允许用户手动关闭窗口(`isCancelable` 参数)
|
||||
- 不可取消时,通过 Win32 API 禁用窗口关闭按钮(灰色不可点击)
|
||||
- 进度值自动 Clamp 到 `[0, 100]` 范围,超出范围时记录 Warn 日志
|
||||
- 自动继承主窗口图标
|
||||
- 使用 Telerik `RadProgressBar` 控件(Crystal 主题)
|
||||
|
||||
### 构造函数参数 | Constructor Parameters
|
||||
|
||||
```csharp
|
||||
public ProgressWindow(
|
||||
string title = "操作进行中", // 窗口标题
|
||||
string message = "请稍候...", // 提示信息
|
||||
bool isCancelable = true, // 是否允许用户关闭窗口
|
||||
ILoggerService? logger = null // 日志服务(可选)
|
||||
)
|
||||
```
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `title` | `string` | `"操作进行中"` | 窗口标题栏文本 |
|
||||
| `message` | `string` | `"请稍候..."` | 进度条上方的提示信息 |
|
||||
| `isCancelable` | `bool` | `true` | `true`:用户可手动关闭;`false`:禁用关闭按钮 |
|
||||
| `logger` | `ILoggerService?` | `null` | 传入日志服务后自动记录窗口生命周期日志 |
|
||||
|
||||
### 公开方法 | Public Methods
|
||||
|
||||
#### UpdateProgress - 更新进度
|
||||
|
||||
```csharp
|
||||
// 线程安全,可从任意线程调用
|
||||
void UpdateProgress(string message, double progress)
|
||||
```
|
||||
|
||||
- `message`:更新提示信息文本
|
||||
- `progress`:进度值(0-100),超出范围自动修正
|
||||
|
||||
#### Close - 关闭窗口
|
||||
|
||||
```csharp
|
||||
// 线程安全,可从任意线程调用(隐藏基类 Window.Close())
|
||||
new void Close()
|
||||
```
|
||||
|
||||
### 基本用法 | Basic Usage
|
||||
|
||||
```csharp
|
||||
using XP.Common.GeneralForm.Views;
|
||||
using XP.Common.Logging.Interfaces;
|
||||
|
||||
public class SomeService
|
||||
{
|
||||
private readonly ILoggerService _logger;
|
||||
|
||||
public SomeService(ILoggerService logger)
|
||||
{
|
||||
_logger = logger?.ForModule<SomeService>()
|
||||
?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
public async Task ExecuteLongOperation()
|
||||
{
|
||||
// 创建进度窗口(不可取消)
|
||||
var progressWindow = new ProgressWindow(
|
||||
title: "数据处理中",
|
||||
message: "正在初始化...",
|
||||
isCancelable: false,
|
||||
logger: _logger);
|
||||
|
||||
// 显示模态窗口(需在 UI 线程调用)
|
||||
// 注意:ShowDialog() 会阻塞,通常配合 Task 使用
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
progressWindow.UpdateProgress("正在加载数据...", 20);
|
||||
await Task.Delay(1000); // 模拟耗时操作
|
||||
|
||||
progressWindow.UpdateProgress("正在处理数据...", 60);
|
||||
await Task.Delay(1000);
|
||||
|
||||
progressWindow.UpdateProgress("即将完成...", 90);
|
||||
await Task.Delay(500);
|
||||
|
||||
progressWindow.UpdateProgress("完成", 100);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 关闭窗口(线程安全)
|
||||
progressWindow.Close();
|
||||
}
|
||||
});
|
||||
|
||||
progressWindow.ShowDialog();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 允许用户取消的用法 | Cancelable Usage
|
||||
|
||||
```csharp
|
||||
// 创建可取消的进度窗口
|
||||
var progressWindow = new ProgressWindow(
|
||||
title: "文件导出",
|
||||
message: "正在导出文件...",
|
||||
isCancelable: true, // 用户可以点击关闭按钮取消
|
||||
logger: _logger);
|
||||
|
||||
progressWindow.ShowDialog();
|
||||
```
|
||||
|
||||
### ViewModel 绑定属性 | ViewModel Binding Properties
|
||||
|
||||
`ProgressWindowViewModel` 继承自 `BindableBase`,提供以下可绑定属性:
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `Title` | `string` | 窗口标题(只读) |
|
||||
| `Message` | `string` | 提示信息文本(可通知) |
|
||||
| `Progress` | `double` | 进度值 0-100(可通知) |
|
||||
| `ProgressText` | `string` | 百分比显示文本,如 `"75%"`(只读,自动计算) |
|
||||
| `IsCancelable` | `bool` | 是否允许用户关闭(只读) |
|
||||
|
||||
### 注意事项 | Notes
|
||||
|
||||
1. `ShowDialog()` 必须在 UI 线程调用,它会阻塞当前线程直到窗口关闭
|
||||
2. `UpdateProgress()` 和 `Close()` 内部已处理跨线程调度,可安全地从后台线程调用
|
||||
3. 当 `isCancelable = false` 时,窗口关闭按钮会被 Win32 API 禁用(灰色),用户无法通过 Alt+F4 或点击关闭
|
||||
4. 进度值超出 `[0, 100]` 范围时会自动修正并记录 Warn 级别日志
|
||||
5. `Close()` 使用 `new` 关键字隐藏基类方法(因 `Window.Close()` 非虚方法),确保通过 `ProgressWindow` 类型引用调用
|
||||
|
||||
---
|
||||
|
||||
## InputDialog 输入对话框
|
||||
|
||||
### 功能特性 | Features
|
||||
|
||||
- 模态输入对话框,居中于父窗口显示,不可调整大小
|
||||
- 自动继承主窗口图标
|
||||
- 按钮文本支持多语言(使用 `Button_OK` / `Button_Cancel` 资源键)
|
||||
- 可选的输入验证委托(`Func<string, string?>`),验证失败时在输入框下方显示红色错误提示
|
||||
- 输入内容变化时自动清除验证错误
|
||||
- 使用 Telerik `RadWatermarkTextBox` 和 `RadButton` 控件(Crystal 主题)
|
||||
- 提供静态 `Show()` 便捷方法,一行代码即可调用
|
||||
|
||||
### 静态方法 | Static Method
|
||||
|
||||
```csharp
|
||||
public static string? Show(
|
||||
string prompt, // 提示文本
|
||||
string title, // 窗口标题
|
||||
string defaultValue = "", // 默认值
|
||||
Func<string, string?>? validate = null, // 验证委托(可选)
|
||||
Window? owner = null // 父窗口(可选)
|
||||
)
|
||||
```
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `prompt` | `string` | 必填 | 输入框上方的提示文本 |
|
||||
| `title` | `string` | 必填 | 窗口标题栏文本 |
|
||||
| `defaultValue` | `string` | `""` | 输入框的初始值 |
|
||||
| `validate` | `Func<string, string?>?` | `null` | 验证委托:返回 `null` 表示通过,返回错误信息则阻止确认 |
|
||||
| `owner` | `Window?` | `null` | 父窗口,设置后对话框居中于父窗口 |
|
||||
|
||||
返回值:用户输入的字符串,取消时返回 `null`。
|
||||
|
||||
### 基本用法 | Basic Usage
|
||||
|
||||
```csharp
|
||||
using XP.Common.GeneralForm.Views;
|
||||
|
||||
// 最简用法,无验证
|
||||
var name = InputDialog.Show("请输入名称:", "新建项目");
|
||||
if (name == null) return; // 用户取消
|
||||
|
||||
// 带默认值
|
||||
var port = InputDialog.Show("请输入端口号:", "配置", "8080");
|
||||
```
|
||||
|
||||
### 带验证的用法 | Usage with Validation
|
||||
|
||||
```csharp
|
||||
// 验证委托:返回 null 表示通过,返回错误信息则显示在输入框下方
|
||||
var groupId = InputDialog.Show(
|
||||
"请输入 Group ID:",
|
||||
"新增 Group",
|
||||
validate: input =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return "ID 不能为空";
|
||||
if (existingIds.Contains(input))
|
||||
return "ID 已存在,请使用不同的 ID";
|
||||
return null; // 验证通过
|
||||
});
|
||||
|
||||
// 验证非负整数
|
||||
var dbNumber = InputDialog.Show(
|
||||
"请输入 DB 块号(非负整数):",
|
||||
"新增 Group",
|
||||
"0",
|
||||
validate: input =>
|
||||
{
|
||||
if (!int.TryParse(input, out int val) || val < 0)
|
||||
return "必须为非负整数";
|
||||
return null;
|
||||
});
|
||||
```
|
||||
|
||||
### 注意事项 | Notes
|
||||
|
||||
1. `Show()` 必须在 UI 线程调用(内部使用 `ShowDialog()`)
|
||||
2. 验证委托在用户点击确定按钮时执行,验证失败不会关闭对话框
|
||||
3. 用户修改输入内容时会自动清除上一次的验证错误提示
|
||||
4. 按钮文本从 XP.Common 资源文件读取(`Button_OK` / `Button_Cancel`),自动跟随应用语言
|
||||
Reference in New Issue
Block a user