【问题标题】:How to prevent a question to be shown in the Confirmation prompt?如何防止在确认提示中显示问题?
【发布时间】:2019-02-18 16:10:00
【问题描述】:

我不想在最终确认中显示一个问题

【问题讨论】:

    标签: c# botframework bots formflow


    【解决方案1】:

    我可以想到三种方法来做到这一点。例如,我将使用包含 FirstName、LastName 和 MiddleName 的表单,其中 MiddleName 是您要隐藏的字段。

    选项 1

    您可以自定义确认步骤以明确列出除一个以外的每个字段:

    public static IForm<MyClass> BuildForm()
    {
        var fieldNames = new[] { nameof(FirstName), nameof(MiddleName), nameof(LastName) };
        var confirmation = new StringBuilder("Is this your selection?");
        var formBuilder = new FormBuilder<MyClass>();
    
        foreach (var name in fieldNames)
        {
            // Add the field to the form
            formBuilder.Field(name);
    
            // Add the field to the confirmation prompt unless it's MiddleName
            if (name != nameof(MiddleName))
            {
                confirmation.AppendLine().Append($"* {{&{name}}}: {{{name}}}");
            }
        }
    
        formBuilder.Confirm(new PromptAttribute(confirmation.ToString()) {
            FieldCase = CaseNormalization.None
        });
    
        return formBuilder.Build();
    }
    

    这可能看起来有点复杂,但这只是一种更动态的说法:

    public static IForm<MyClass> BuildForm()
    {
        var formBuilder = new FormBuilder<MyClass>()
            .Field(nameof(FirstName))
            .Field(nameof(MiddleName))
            .Field(nameof(LastName))
            .Confirm(new PromptAttribute("Is this your selection?\n* {&FirstName}: {FirstName}\n* {&LastName}: {LastName}") { FieldCase = CaseNormalization.None })
            ;
    
        return formBuilder.Build();
    }
    

    注意这里使用pattern language

    选项 2

    您可以在确认步骤中使某个字段处于非活动状态。这有点棘手,因为您需要确保该字段在所有其他步骤中都处于活动状态。在我的示例中,这是通过为每个字段设置 NextDelegate 来实现的。在这种情况下,MiddleName 应标记为可选。

    [Optional]
    public string MiddleName { get; set; }
    
    public static IForm<MyClass> BuildForm()
    {
        NextDelegate<MyClass> next = (value, state) =>
        {
            // Make sure MiddleName is active during most steps
            state._isMiddleNameActive = true;
            return new NextStep();
        };
    
        var formBuilder = new FormBuilder<MyClass>()
            .Field(new FieldReflector<MyClass>(nameof(FirstName)).SetNext(next))
            .Field(new FieldReflector<MyClass>(nameof(MiddleName)).SetNext(next)
                .SetActive(state => state._isMiddleNameActive))
            .Field(new FieldReflector<MyClass>(nameof(LastName)).SetNext(next))
            ;
    
        formBuilder.Confirm(async state =>
            {
                // Make sure MiddleName is inactive during the confirmation step
                state._isMiddleNameActive = false;
    
                // Return the default confirmation prompt
                return new PromptAttribute(
                    formBuilder.Configuration.Template(TemplateUsage.Confirmation));
            });
    
        return formBuilder.Build();
    }
    
    // This private field isn't included in the form but is accessible via the form's state
    private bool _isMiddleNameActive;
    

    选项 3

    您可以使用custom prompter。这有点高级,但它给你最大的控制权。

    public static IForm<MyClass> BuildForm()
    {
        var formBuilder = new FormBuilder<MyClass>()
            .Prompter(PromptAsync)
            ;
    
        return formBuilder.Build();
    }
    
    /// <summary>
    /// Here is the method we're using for the PromptAsyncDelgate.
    /// </summary>
    private static async Task<FormPrompt> PromptAsync(IDialogContext context,
        FormPrompt prompt, MyClass state, IField<MyClass> field)
    {
        var preamble = context.MakeMessage();
        var promptMessage = context.MakeMessage();
    
        // Check to see if the form is on the confirmation step
        if (field.Name.StartsWith("confirmation"))
        {
            // If it's on the confirmation step,
            // we want to remove the MiddleName line from the text
            var lines = prompt.Prompt.Split('\n').ToList();
            var middleNameField = field.Form.Fields.Field(nameof(MiddleName));
            var format = new Prompter<MyClass>(
                middleNameField.Template(TemplateUsage.StatusFormat), field.Form, null);
            var middleNameLine = "* " + format.Prompt(state, middleNameField).Prompt;
            lines.RemoveAll(line => line.StartsWith(middleNameLine));
            prompt.Prompt = string.Join("\n", lines);
        }
    
        if (prompt.GenerateMessages(preamble, promptMessage))
        {
            await context.PostAsync(preamble);
        }
    
        await context.PostAsync(promptMessage);
    
        return prompt;
    }
    

    【讨论】:

    • 非常感谢,我会努力的。
    • 效果很好。
    猜你喜欢
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 2011-03-15
    • 1970-01-01
    相关资源
    最近更新 更多