This commit is contained in:
chfei committed 2026-11-10 16:33:51 +08:00
1 parent 3135189ea3
commit a003d90b0e
21 files changed
+754 -145

No files matched your search

+42 -35
View File
@@ -60,6 +60,9 @@ DataContext="{core:DISource Type=local:DialogViewModel}">
**`BindingProxy` 映射关系**:`Data="{Binding}"` 把 ViewModel 存到 `BindingProxy.Data`。引用时 `Path=Data.SelectedItem` 中 `Data` 对应 `BindingProxy.Data`(即 ViewModel)。
### 文字只读显示
尽量使用 `TextBlock` 而不是 `Label`
### DataTemplate(CellTemplate)中
Command 用 CommandProxy,行数据用 `{Binding}`:
@@ -262,6 +265,24 @@ C# 侧:`"#FF5733".toColor()`、`"#80000000".toColor()`。
</Style>
```
## 顺序排列与间距布局
**页面排版需要横向、纵向顺序排列或简单自动换行时,优先使用 `wpf:SpacingStackPanel`。** 普通堆叠布局通过 `Orientation` 指定方向,需要换行时设置 `ChildWrapping="True"`。
- 优先用 `HorizontalSpacing` / `VerticalSpacing` 统一控制子项间距,避免逐项设置重复的 `Margin`;容器外边距和个别元素的特殊偏移仍按需使用 `Margin`。
- 需要统一子项尺寸或对齐时,按需设置 `ItemWidth`、`ItemHeight`、`ItemHorizontalAlignment`、`ItemVerticalAlignment`。
- “文字 + 简单内容”可由 `wpf:TitleContent` 组成,再用 `wpf:SpacingStackPanel` 排列多个字段。
- 需要行列划分、跨行跨列、重叠或虚拟化时,使用满足这些要求的布局容器,不强行替换为 `SpacingStackPanel`。
- 属性及用法见 [max-common-wpf SpacingStackPanel 参考](../skills/max-common-wpf/references/api.md#controlsspacingstackpanelcs)。
## 文字与简单内容布局
**页面排版遇到“说明文字 + 简单内容”(如输入框、选择器、按钮等输入或点击控件)时,优先使用 `wpf:TitleContent`。** 将说明文字放在 `Title`,交互控件作为内容,避免为同一组合另用 `TextBlock` 配合 `Grid` / `StackPanel` 手工拼接。
- 按布局设置 `Placement`;左侧标题表单优先使用 `Placement="Left"`,并按需设置 `TitleWidth`、`TitleVerticalAlignment="Center"` 和 `LeftTitlePadding`,保持同组字段对齐。
- 内容控件仍自行配置绑定、命令、输入长度和可访问名称;`TitleContent` 只负责标题与内容的布局。
- 属性及用法见 [max-common-wpf TitleContent 参考](../skills/max-common-wpf/references/api.md#controlstitlecontentcs)。
## 布局注释
主要布局分块/区域前加 `<!-- -->` 注释标明用途。复杂视图(多面板、多 Tab、对话框)必须注释;简单单控件视图可省略:
@@ -302,48 +323,34 @@ C# 侧:`"#FF5733".toColor()`、`"#80000000".toColor()`。
## 枚举绑定
### EnumDisplayConverter(XAML)
**页面的枚举选项绑定优先使用 `EnumBindingMarkup`(`EnumBindingMarkupExtension`)生成 ItemsSource,配合 `EnumBindingExtension.SelectedEnum` 绑定选中的枚举值。** 不要仅为列出枚举值,在 ViewModel 中额外定义 `Enum.GetValues` 列表或在 XAML 中硬编码选项。
- 显示名优先使用 MAX.Common.WPF 自带的 `EnumDisplayConverter`,显式传入标记扩展的 `Converter`;未传入时默认显示枚举成员名称。
- `DisplayMemberPath="Display"` 用于显示名称,`SelectedValuePath="Value"` 对应枚举值本身。
- 系统初始化、视图加载前配置一次 `EnumDisplayConverter.EnumDisplayManager = new EnumDisplayManagerWPF(null);`;已有自定义显示管理器时复用现有配置。
- 仅显示单个枚举值的文本时,直接绑定该属性并使用 `EnumDisplayConverter`,无需生成选项列表。
### ComboBox 绑定枚举
`xmlns:wpf="MAX.WPF"`,`xmlns:local` 指向业务枚举命名空间:
```xml
<UserControl.Resources>
<conv:EnumDisplayConverter x:Key="EnumDisplayConverter"/>
<wpf:EnumDisplayConverter x:Key="EnumDisplayConverter" />
</UserControl.Resources>
<!-- 直接绑定枚举值 -->
<TextBlock Text="{Binding Status, Converter={StaticResource EnumDisplayConverter}}"/>
<ComboBox
ItemsSource="{wpf:EnumBindingMarkup EnumType={x:Type local:MyStatus},
Converter={StaticResource EnumDisplayConverter}}"
DisplayMemberPath="Display"
SelectedValuePath="Value"
wpf:EnumBindingExtension.SelectedEnum="{Binding SelectedStatus, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<!-- 只读显示单个枚举值 -->
<TextBlock Text="{Binding Status, Mode=OneWay, Converter={StaticResource EnumDisplayConverter}}" />
```
### ComboBox 绑定枚举(推荐:ViewModel 提供列表)
```csharp
// ViewModel
public IReadOnlyList<MyStatus> StatusList { get; } = Enum.GetValues(typeof(MyStatus)).Cast<MyStatus>().ToList();
public MyStatus SelectedStatus
{
get => GetProperty(() => SelectedStatus);
set => SetProperty(() => SelectedStatus, value);
}
```
```xml
<ComboBox ItemsSource="{Binding StatusList}"
SelectedItem="{Binding SelectedStatus}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ., Converter={StaticResource EnumDisplayConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
```
### C# 获取枚举显示文本
```csharp
string displayText = MyStatus.Active.GetEnumDisplay();
```
EnumDisplayService 内部实现和自定义逻辑详见 `reference-enum-display` skill。
初始化命名空间、Description 显示、空选项等完整用法见 [max-common-wpf 枚举绑定参考](../skills/max-common-wpf/references/api.md#markupextensionsenumbindingmarkupextensioncs)。自定义枚举显示管理器见 `reference-enum-display` skill。
## MarkupExtension 示例