Я могу придумать три способа сделать это.В качестве примера я буду использовать форму с именами 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();
}
Обратите внимание, что здесь используется язык шаблонов.
Вариант 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
Вы можете использовать пользовательский подсказчик .Это немного продвинутый, но дает вам максимальный контроль.
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;
}