如何根据 FormFlow 中其他字段的值设置不同的字段打开和关闭

How to set different fields on and off on basis of value of other field in FormFlow

我正在使用 FormFlow 通过 botFrameWork(C#) 构建我的机器人。我想请用户从四个报告中选择一个,并根据选择打开和关闭某些字段,并仅询问与选择相关的问题。

以下是报告类型的枚举:

public enum ReportType
    {
        Application = 1,
        Emotion,
        AppVsEmotion,
        Help
    }

以下是所有字段:

public bool AskToChooseReport = true;

[Prompt("What kind of report you would like? {||}")]
public ReportType? Report { get; set; }

[Prompt("What is the application name?")]
public string ReportApplicationName { get; set; }


[Prompt("Please enter the emotion name? {||}")]
public string EmotionName { get; set; }

[Prompt("What is starting date (MM-DD-YYYY) for report?{||}")]
public string StartDate { get; set; }

[Prompt("What is the end date (MM-DD-YYYY) for report? {||}")]
public string EndDate { get; set; }

public string ReportRequest = string.Empty;

我有四种情况:

情况 1:如果用户选择 Application,那么我只想询问用户有关 ReportApplicationNameStartDate, 结束日期

情况 2:如果用户选择 Emotion,那么我只想询问用户有关 EmotionNameStartDate, 结束日期

情况 3:如果用户选择 AppVsEmotion,我想询问用户关于 ReportApplicationNameEmotionName开始日期结束日期

情况 4:如果用户选择 帮助,那么我只想询问 ReportApplicationNameStartDate, 结束日期

我尝试执行以下操作,但它不起作用:

public static IForm<StandardInfoForm> BuildForm()
        {
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously

            var parser = new Parser();
            return new FormBuilder<StandardInfoForm>()
                .Message("Welcome to reporting information!!")
                .Field(new FieldReflector<StandardInfoForm>( nameof(Report))
                    .SetActive( state => state.AskToChooseReport)
                    .SetNext( (value, state) =>
                    {
                        var selection = (ReportType)value;
                        if (selection == ReportType.Application)
                        {
                            state.ReportRequest = "application";
                            return new NextStep(new[] { nameof(ReportApplicationName) });
                        }
                        else if (selection == ReportType.Emotion)
                        {
                            state.ReportRequest = "emotion";
                            return new NextStep(new[] { nameof (EmotionName) });
                        }
                        else if (selection == ReportType.AppVsEmotion)
                        {
                            state.ReportRequest = "application,emotion";
                            return new NextStep(new[] { nameof (ReportApplicationName), nameof(EmotionName) });
                        }
                        else if (selection == ReportType.Help)
                        {
                            state.ReportRequest = "help";
                            return new NextStep(new[] { nameof(ReportApplicationName) });
                        }
                        else
                        {
                            return new NextStep();
                        }
                    }))               
                .Field(nameof(StartDate))
                .Field(nameof(EndDate), EndReportDateActive)                              
                .Confirm("Would you like to confirm.Yes or No")
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
                .Build();

        }

如果我太天真了,请帮助我。我试图遵循这个:

Microsoft.Bot.Builder.FormFlow.FormCanceledException 发生是因为 ReportApplicationName 不是表单生成器中的字段之一。如果将 .Field(nameof(ReportApplicationName)) 添加到构建中,则不会发生异常。

您还需要在 ReportApplicationNameEmotionName 步骤中使用 .Field 的 ActiveDelegate,因为有时您想跳过它们。从 ActiveDelegate 返回 false 将完成此操作。

注意:我在枚举中将 Emotions 更改为 Feelings,因为 FormBuilder 在 EmotionAppVsEmotion 之间的相似性方面遇到了麻烦,不过这应该会让您朝着正确的方向前进:

public enum ReportType
    {
        Application = 1,
        Feelings,
        AppVsEmotion,
        Help
    }

    [Serializable]
    public class StandardInfoForm
    {
        public bool AskToChooseReport = true;

        [Prompt("What kind of report you would like? {||}")]
        public ReportType? Report { get; set; }

        [Prompt("What is the application name? {||}")]
        public string ReportApplicationName { get; set; }


        [Prompt("Please enter the emotion name?  {||}")]
        public string EmotionName { get; set; }

        [Prompt("What is starting date (MM-DD-YYYY) for report?{||}")]
        public string StartDate { get; set; }

        [Prompt("What is the end date (MM-DD-YYYY) for report? {||}")]
        public string EndDate { get; set; }

        public string ReportRequest = string.Empty;

        public static IForm<StandardInfoForm> BuildForm()
        {

            var parser = new Parser();
            return new FormBuilder<StandardInfoForm>()
                .Message("Welcome to reporting information!!")
                .Field(new FieldReflector<StandardInfoForm>(nameof(Report))
                            .SetActive(state => state.AskToChooseReport)
                            .SetNext(SetNext))
                .Field(nameof(ReportApplicationName), state => state.ReportRequest.Contains("application"))
                .Field(nameof(EmotionName), state => state.ReportRequest.Contains("emotion"))
                .Field(nameof(StartDate))
                .Field(nameof(EndDate), EndReportDateActive)
                .Confirm("Would you like to confirm.Yes or No")
            .Build();

        }

        private static NextStep SetNext(object value, StandardInfoForm state)
        {
            var selection = (ReportType)value;
            if (selection == ReportType.Application)
            {
                state.ReportRequest = "application";
                return new NextStep(new[] { nameof(ReportApplicationName) });
            }
            else if (selection == ReportType.Feelings)
            {
                state.ReportRequest = "emotion";
                return new NextStep(new[] { nameof(EmotionName) });
            }
            else if (selection == ReportType.AppVsEmotion)
            {
                state.ReportRequest = "application,emotion";
                return new NextStep(new[] { nameof(ReportApplicationName) });
            }
            else if (selection == ReportType.Help)
            {
                state.ReportRequest = "help";
                return new NextStep(new[] { nameof(ReportApplicationName) });
            }
            else
            {
                return new NextStep();
            }
        }