我正在使用此自定义类来制作自定义提示。
我修改了TryParse方法。如果用户没有选择任何选项,我想将消息转发到第一个对话框。
代码:
var promptOptions = new CancelablePromptOptions<string>(MyDictionary.ChooseOneOfTheFollowingOptions, cancelPrompt: "cancel", options: MyHelper.GetOptios(), promptStyler: PromptStyler);
CancelablePromptChoice<string>.Choice(context, OptionSelected, promptOptions);
我正在尝试覆盖UcculablePromptoptions类中的TryParse功能:
protected override bool TryParse(IMessageActivity message, out T result)
{
if (IsCancel(message.Text))
{
result = default(T);
return true;
}
bool b = base.TryParse(message, out result);
if (!b)
Conversation.SendAsync(message, () => new MyFirstDialog());
return base.TryParse(message, out result);
}
请注意代码中的myfirstdialog。我想通过当前消息重新创建第一个对话框。
目标:如果用户选择一些存储更多选项的对话框,并且第一个"选择"无效,我想重新创建myfirstdialog。
有什么想法吗?
编辑:
myfirstdialog是我从消息控制器中调用的第一个模式。
await Conversation.SendAsync(activity, () => new MyFirstDialog());
我正在从myfirstdialog中调用当前的didialog:
context.Call(new CurrentDialog(), CurrentDialog.HandleOptions);
以下是如何返回您的初始对话框的示例,以最低级别开始。
CANCULABL PROMPTCHOICE 代码:
在这里,您让基本实现执行" tryparse",但是如果它不匹配,则可以处理(通过返回真实并保持值(,避免重试
protected override bool TryParse(IMessageActivity message, out T result)
{
if (IsCancel(message.Text))
{
result = default(T);
return true;
}
var parsingTriedSucceeded = base.TryParse(message, out result);
// here you know if you found one of the options or not, and if not you override
if (!parsingTriedSucceeded)
{
result = (T)Convert.ChangeType(message.Text, typeof(T));
return true;
}
else
{
return parsingTriedSucceeded;
}
}
CurrentDialog 代码:
在此代码中,您将在选项中处理默认值(t(回复(这是此对话框在提示后恢复时调用的方法(。通过执行context.Done<string>(null);
,您将结束此对话框,然后返回MyFirstDialog
[Serializable]
public class CurrentDialog : IDialog<string>
{
public async Task StartAsync(IDialogContext context)
{
var promptOptions = new CancelablePromptOptions<string>(MyDictionary.ChooseOneOfTheFollowingOptions, cancelPrompt: "cancel", options: MyHelper.GetOptions(), promptStyler: PromptStyler);
CancelablePromptChoice<string>.Choice(context, OptionSelected, promptOptions);
}
private async Task OptionSelected(IDialogContext context, IAwaitable<string> result)
{
var chose = await result;
string answer = chose.ToString();
switch (answer)
{
case HelpEnumerator.Agenda:
await EventHelper.GetEventAgenda(context);
context.Done<string>(null);
break;
case HelpEnumerator.Register:
context.Call(new RegistrationDialog(), RegistrationDialog.Resume);
context.Done<string>(null);
break;
case HelpEnumerator.Speakers:
await EventHelper.GetSpeakers(context);
context.Done<string>(null);
break;
case HelpEnumerator.Tickets:
await EventHelper.GetTickets(context);
context.Done<string>(null);
break;
default:
context.Done(answer);
break;
}
}
}
myfirstdialog 代码:
因此,最后在您的myfirstdialog中,您必须使用简历方法从CurrentDialog处理此返回:
// Somewhere in your logic...
context.Call(new CurrentDialog(), ResumeAfterCurrentDialog);
// On your class:
private async Task ResumeAfterCurrentDialog(IDialogContext context, IAwaitable<string> result)
{
// You are entering here after "context.Done(...)" in the CurrentDialog. To know the "result" value, take a look at what in the OptionSelected in CurrentDialog => it can be null for the options of the list, or the value in "answer" if it's not one of the options
// So we only have to test if it's not null, and then send the message again to the bot by using the "context.Activity" value
var resultText = await result;
if (resultText != null)
{
// Send the message again. It's already the message stored in context.Activity ;)
IMessageActivity msg = (IMessageActivity)context.Activity;
await this.MessageReceivedAsync(context, new AwaitableFromItem<IMessageActivity>(msg));
}
}