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

4.4 KiB
Raw Blame History

name, description, disable-model-invocation
name description disable-model-invocation
add-dialog 在 PipeReviewReport 客户端中新建一个弹窗对话框,包含 Parameter record、`DialogViewModelOkCancel` 和调用方的注册写法。 当用户需要新建弹窗、编辑对话框、确认框时使用。 false

新建弹窗对话框

文件组织

Dialog 的所有代码(UserControl、Parameter、ViewModel)写在同一个 .xaml.cs 文件中,放在 Views/Dialogs/ 目录下。


Step 1 — Dialog 文件(.xaml.cs)

namespace PipeReviewReport.<模块名>.Views.Dialogs;

// UserControl code-behind(保持最简)
public partial class XxxDialog : UserControl
{
    public XxxDialog() => InitializeComponent();
}

// Parameter:record class,构造函数参数 = 传入值,属性 = 传出值
internal record XxxDialogParameter(XxxItem Item)
{
    public XxxItem? Result { get; set; }
}

// ViewModel
internal class XxxDialogViewModel(
    // 注入所需服务
) : DialogViewModelOkCancel<XxxDialogParameter>
{
    // 绑定到 View 的数据
    public SomeModel EditTarget { get; } = new();

    protected override void OnInitialized()
    {
        // Parameter 和 ParentViewModel 均已就绪,在此读取传入值
        ConfirmDialogCommand.Content = "保存";
        CancelDialogCommand.Content = "取消";
        if (Parameter.Item != null)
        {
            DialogTitle = "编辑";
            // 将 Parameter.Item 映射到 EditTarget
        }
        else
        {
            DialogTitle = "新增";
        }
    }

    protected override bool Validate(out string message)
    {
        // 校验;失败时 message 非空并 return false
        message = string.Empty;
        return true;
    }

    protected override void ShowErrorDialog(string message)
    {
        // 基类默认用 System.Windows.MessageBox,业务弹窗请覆盖为 MessageBoxService
        MessageBoxService.ShowWarning(message);
    }

    protected override bool OnConfirmed()
    {
        // 将结果写回 Parameter;唯一性等异步校验建议放调用方
        Parameter.Result = EditTarget;
        return true;
    }
}

Step 2 — Dialog View(XAML)

先读取 Source/XAML_Preset.txt 中 -------------- Dialog -------------- 区段复制 xmlns,注意:

  • Style="{StaticResource DialogStyle.Base}"(StaticResource,不是 DynamicResource)
  • DataContext="{core:DISource Type=local:XxxDialogViewModel}"

Step 3 — 调用方 View(XAML)注册

在调用方 View 的 XAML 中,用 f:DialogService 注册弹窗:

<dxmvvm:Interaction.Behaviors>
    <f:DialogService Name="XxxDialog" ContentType="{x:Type dialogs:XxxDialog}"/>
</dxmvvm:Interaction.Behaviors>

其中 dialogs 命名空间需在文件头声明:

xmlns:dialogs="clr-namespace:PipeReviewReport.<模块名>.Views.Dialogs"

Step 4 — 调用方 ViewModel 注册与调用

// 注册服务(属性名必须和 XAML 中 Name 一致)
public IDialogServiceEx XxxDialog => GetService<IDialogServiceEx>(nameof(XxxDialog));

// 打开弹窗(OK / Cancel)
public IDelegateCommand AddCommand => field ??= new AsyncCommand(Add);
private async Task Add()
{
    XxxDialogParameter parameter = new(null);
    if (XxxDialog.ShowOKCancel(this, parameter))
    {
        // 用户点了 OK,从 parameter.Result 取结果
        XxxItem result = parameter.Result;
        await Task.CompletedTask;
    }
}

可用方法(IDialogServiceEx):

方法 说明
ShowOKCancel(parentVM, parameter) OK / Cancel,返回 bool(true = OK)
ShowDialog(parentVM, parameter) 返回 DialogResult(含命令)

检查清单

  • Parameter 使用 record 类型,构造参数为传入值,属性为传出值
  • ViewModel 继承 DialogViewModelOkCancel<TParameter>(或 DialogViewModelOk / DialogViewModel)
  • 传出结果在 OnConfirmed() 中写入 Parameter.Result
  • 覆盖 ShowErrorDialog,走 MessageBoxService 而非 System.Windows.MessageBox
  • Dialog View 使用 Style="{StaticResource DialogStyle.Base}"
  • 调用方 XAML 已声明 f:DialogService,Name 与 ViewModel 属性名一致
  • 调用方 ViewModel 属性名与 nameof(XxxDialog) 一致
  • 异步唯一性校验放在调用方(弹窗 OnConfirmed 保持同步)
  • 对话框内输入框已显式 MaxLength="{x:Static shared:InputLimits.Path/Text}"(完整路径用选择器)