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

房东的猫 提交于 2019-12-08 05:07:41

问题


I am using FormFlow to build my bot using botFrameWork(C#). I want to ask user to choose one of four reports and on the basis of selection I want to turn on and off certain fields and ask only those questions which are relevant to the selection.

Follwoing is the enum for report types:

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

Here are all the fields:

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;

I have four cases:

Case 1: If user slects Application, Then i only want to ask user about ReportApplicationName, StartDate, EndDate

Case 2: If user selects Emotion, Then i only want to ask user about EmotionName and StartDate, EndDate

Case 3: If user selects AppVsEmotion, The i want to ask user about both ReportApplicationName, EmotionName and StartDate, EndDate

Case 4: If user selects Help, then i only want to ask about ReportApplicationName, StartDate, EndDate

I tried to do following but it doesn't work:

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();

        }

Please help me if I am being too naive. I have tried to follow this: Change Flow Of Message In Microsoft Bot FrameWork


回答1:


Microsoft.Bot.Builder.FormFlow.FormCanceledException is happening because ReportApplicationName is not one of the fields in the form builder. If you add .Field(nameof(ReportApplicationName)) to the build, the exception will not occur.

You'll also need to use the .Field's ActiveDelegate for the ReportApplicationName and EmotionName steps, since sometimes you want to skip them. Returning false from the ActiveDelegate will accomplish this.

Note: I changed Emotions to Feelings in the enum, because FormBuilder was having trouble with the similarity between Emotion and AppVsEmotion This should get you going in the right direction though:

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();
            }
        }


来源:https://stackoverflow.com/questions/44568178/how-to-set-different-fields-on-and-off-on-basis-of-value-of-other-field-in-formf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!