如何防止在确认提示中显示问题?
How to prevent a question to be shown in the Confirmation prompt?
我不想在最终确认中出现一个问题
我可以想到三种方法来做到这一点。例如,我将使用包含 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;
}
我不想在最终确认中出现一个问题
我可以想到三种方法来做到这一点。例如,我将使用包含 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;
}