从自定义提示符到另一个对话框



我正在使用此自定义类来制作自定义提示。

我修改了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));
    }
}

相关内容

最新更新