我正在使用this自定义类来制作自定义提示。
我修改了tryParse方法。如果用户没有选择任何选项,我想将消息转发到第一个Dialog。
代码:
var promptOptions = new CancelablePromptOptions<string>(MyDictionary.ChooseOneOfTheFollowingOptions, cancelPrompt: "cancel", options: MyHelper.GetOptios(), promptStyler: PromptStyler);
CancelablePromptChoice<string>.Choice(context, OptionSelected, promptOptions);
我正在尝试覆盖CancelablePromptOptions类中的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。我想用当前消息重新创建第一个对话框。
目标:如果用户选择了一些存储更多选项的Dialog,并且第一个“choose”无效,我想重新创建MyFirstDialog。
有什么想法吗?
编辑:
MyFirstDialog是我从Messages控制器调用的第一个IDialog。
await Conversation.SendAsync(activity, () => new MyFirstDialog());
我从MyFirstDialog调用当前的IDialog:
context.Call(new CurrentDialog(), CurrentDialog.HandleOptions);
答案 0 :(得分:1)
以下是关于如何返回初始对话框的示例,从最低级别开始。
CancelablePromptChoice 代码:
在这里你让基本实现执行“TryParse”,但是如果它不匹配你将处理它(通过返回true并保持值),避免重试
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 代码:
在此代码中,您将在OptionSelected中处理默认(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中你必须使用resume方法处理来自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));
}
}