如何根据 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,那么我只想询问用户有关 ReportApplicationName、StartDate, 结束日期
情况 2:如果用户选择 Emotion,那么我只想询问用户有关 EmotionName 和 StartDate, 结束日期
情况 3:如果用户选择 AppVsEmotion,我想询问用户关于 ReportApplicationName、EmotionName 和 开始日期、结束日期
情况 4:如果用户选择 帮助,那么我只想询问 ReportApplicationName、StartDate, 结束日期
我尝试执行以下操作,但它不起作用:
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)) 添加到构建中,则不会发生异常。
您还需要在 ReportApplicationName
和 EmotionName
步骤中使用 .Field 的 ActiveDelegate,因为有时您想跳过它们。从 ActiveDelegate 返回 false 将完成此操作。
注意:我在枚举中将 Emotions 更改为 Feelings,因为 FormBuilder 在 Emotion
和 AppVsEmotion
之间的相似性方面遇到了麻烦,不过这应该会让您朝着正确的方向前进:
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();
}
}
我正在使用 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,那么我只想询问用户有关 ReportApplicationName、StartDate, 结束日期
情况 2:如果用户选择 Emotion,那么我只想询问用户有关 EmotionName 和 StartDate, 结束日期
情况 3:如果用户选择 AppVsEmotion,我想询问用户关于 ReportApplicationName、EmotionName 和 开始日期、结束日期
情况 4:如果用户选择 帮助,那么我只想询问 ReportApplicationName、StartDate, 结束日期
我尝试执行以下操作,但它不起作用:
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)) 添加到构建中,则不会发生异常。
您还需要在 ReportApplicationName
和 EmotionName
步骤中使用 .Field 的 ActiveDelegate,因为有时您想跳过它们。从 ActiveDelegate 返回 false 将完成此操作。
注意:我在枚举中将 Emotions 更改为 Feelings,因为 FormBuilder 在 Emotion
和 AppVsEmotion
之间的相似性方面遇到了麻烦,不过这应该会让您朝着正确的方向前进:
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();
}
}