Files
Store.Management/.agents/skills/max-common-wpf/SKILL.md
T
2026-10-27 19:01:56 +08:00

5.8 KiB
Raw Blame History

name, description
name description
max-common-wpf 在 Windows WPF 项目中接入和使用 MAX.Common.WPF 的控件、转换器、附加行为、枚举绑定、视图生命周期、防抖和虚拟化功能。适用于明确使用 MAX.Common.WPF 或已引用该库的界面开发;不适用于 WinUI、Avalonia 或 MAUI。

MAX.Common.WPF 功能使用

根据消费项目需求使用现有 WPF 能力。此 Skill 可独立复制使用,不要求安装其他 Skill,也不包含 NuGet 包或原始库源码。

接入与参考版本

  • 先检查 .csproj、集中版本配置、App.xaml 资源字典和既有样式,不改变项目的应用框架或依赖管理方式。
  • 基于 2026-10-27 源码快照:MAX.Common.WPF 1.4.23,依赖 MAX.Common 1.4.17;目标为 net472;net48;net481;net6.0-windows;net7.0-windows;net8.0-windows;net9.0-windows;net10.0-windows。这些是参考版本,不代表最新发布版本。
  • 优先使用项目现有兼容版本。新接入时选与项目 TFM 匹配的包资产,现代 .NET 项目设置 <UseWPF>true</UseWPF> 并使用 Windows TFM;不要将普通 netstandard 类库改成 WPF。
  • 普通项目通过 PackageReference Include="MAX.Common.WPF" Version="1.4.23" 接入,集中包管理按现有模式拆分版本。MAX.Common 由包依赖传入,通常无需重复添加;MAX.Core、通知系统与 IoC 不属于本 Skill 必需依赖。

功能定位

按任务读取 功能索引。具体命名空间、属性和方法在 常用 API 声明 中按类型搜索。声明摘录没有完整方法体;行为不明确时查看当前安装包 XML 文档、反射或可用源码,再以编译和运行验证。消费项目没有原仓库也应能使用本指南。

XAML 资源入口

程序集声明了 xmlns:wpf="MAX.WPF"。控件样式和共享转换器位于 Resources/Generic.xaml,不要猜成 Themes/Generic.xaml。需要这些资源时,在现有 Application.Resources 的 MergedDictionaries 中合并一次:

<ResourceDictionary Source="/MAX.Common.WPF;component/Resources/Generic.xaml"/>

页面最小示例(绑定属性由页面的 DataContext 提供):

<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:wpf="MAX.WPF">
    <StackPanel.Resources>
        <wpf:Boolean2VisibilityConverter x:Key="ShowWhenTrue"/>
    </StackPanel.Resources>
    <wpf:NumberBox Minimum="0" Maximum="100" Increment="1"
                   Value="{Binding Amount, Mode=TwoWay}"/>
    <TextBlock Text="处理中"
               Visibility="{Binding IsBusy, Converter={StaticResource ShowWhenTrue}}"/>
</StackPanel>

不要假设所有转换器都已登记为全局资源;可以显式实例化所需转换器。Boolean2VisibilityConverter 的 false 和非 bool 输入返回 Collapsed。

常见集成约束

  • 枚举选择优先使用 EnumBindingMarkupExtension 配合 EnumBindingExtension.SelectedEnum;EnumBindingComboBox 已标记 Obsolete。标记扩展返回 EnumBindingItem(Display、Value),不是裸枚举列表;显示与选择路径需要对应包装对象。
  • ViewModelBase 继承 MAX.Common.Models.BindModelBase。只有需要视图事件与 Loaded / LoadedOnce / Unloaded 钩子时才采用;不要替换现有框架的基类。通过 AssignView(view) 关联一次稳定视图后才能使用其 Dispatcher。
  • ViewModelExtension.AutoAssignViewModel 仅监听启用后的 DataContextChanged,不会立即处理已经设置的 DataContext;需要先启用再设置 DataContext,或显式 AssignView。基类没有提供完整的换视图解绑流程,不要把同一实例反复关联不同视图。
  • DebounceDispatcher.Debounce(TimeSpan, Action) 基于 DispatcherTimer,应从 UI 线程调用并复用实例;不能每次输入都创建新实例。
  • AsyncDebouncer.Invoke(Func<Task>) 通过 Task.Run 执行回调,UI 更新要回到 Dispatcher。新调用取消等待,不会取消已经开始的业务任务;回调内处理业务异常,搜索结果另行防止旧请求覆盖新请求。它没有可 await 的 InvokeAsync 或公开 Cancel/Dispose API。
  • DispatcherHelper.RunInDispatcher 在非目标线程同步 Invoke;省略 Dispatcher 的重载依赖 Application.Current。不要在 UI 线程同步等待同时需要 Dispatcher 的后台任务。
  • 虚拟化依赖有限可视区域、滚动宿主和 ItemsPanel 配置。VirtualizingItemsControl 默认使用 VirtualizingStackPanel,需要换行时显式设置 VirtualizingWrapPanel。不能仅添加面板便承诺大数据性能。
  • 通用命令在 MAX.Common.Commands,不是 WPF.Commands。MethodCommand / AsyncMethodCommand 的 T 需引用类型或可空值类型,状态变化手动 RaiseCanExecuteChanged;异步命令委托需自行处理业务异常。

枚举绑定示例

已有 xmlns:local 指向业务枚举命名空间、SelectedStatus 是 Status 属性时:

<ComboBox ItemsSource="{wpf:EnumBindingMarkup EnumType={x:Type local:Status}}"
          DisplayMemberPath="Display"
          SelectedValuePath="Value"
          wpf:EnumBindingExtension.SelectedEnum="{Binding SelectedStatus, Mode=TwoWay}"/>

允许空选项时使用 AllowNull 并让业务属性可空;自定义显示通过扩展的 Converter 提供,勿假设自动读取所有枚举描述标记。

验证与交付

构建实际消费项目的目标框架。运行窗口检查资源解析、DataContext、双向绑定、命令、UI 线程和卸载后的行为。触及虚拟化时用实际数据与滚动验证;触及防抖时检查连续输入和结果乱序。仅编译不能证明 XAML 资源与运行时绑定正确。交付时列出改动文件、包版本和实际验证情况,可按需继续代码审查。