我尝试改编以下示例: ChoiceFlow 对话框示例
我有一个从 ComponentDialog 派生的类,带有瀑布步骤。 一旦我获得了足够的信息,我就会开始一个新的对话框(TroubleshootingDialog)。
当 TroubleshootingDialog 结束时(它通过调用 EndDialogAsync 结束),我想分析子对话框中收集的数据并采取适当的操作。
为此,我尝试重写 ResumeDialogAsync,但当子对话框结束时它不会触发。
public class ProductFlowDialog : ComponentDialog
In constructor:
var guidedWaterfall = new WaterfallStep[]
{
LoadChoiceFlowItems,
PromptChoice,
ActOnPromptResult,
};
public async Task<DialogTurnResult> PromptChoice(WaterfallStepContext sc, CancellationToken cancellationToken)
{
if ( something)
{
}
else
{
// Here we have enough information to start new dialog.
var result = await sc.ReplaceDialogAsync("TroubleshootingDialog", wOptions);
return result;
}
public override Task<DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken))
{
// Do something
}
}
我遇到了完全相同的问题。经过几个小时的绞尽脑汁,我终于弄清楚了问题的原因,至少对我来说是这样。为了他人的利益,这是我的解决方案。
我的情况是在 ComponentDialog 内显示 WaterfallDialog,用于添加其他对话框类型,例如 TextPrompt、AttachmentPrompt 等。
幸运的是,我启用了详细日志记录,并注意到 Bot 框架正在将其遵循的流程记录到输出窗口。当我尝试结束子瀑布对话框时,我看到如下所示的日志输出:
‘消息’==>结束对话框==>文本提示
'消息' ==> ResumeDialog ==> ChildWaterfallDialog
'消息' ==> EndDialog ==> ChildWaterfallDialog
'消息' ==> EndDialog ==> ChildComponentDialog
'消息' ==> ResumeDialog ==> TextPrompt
我希望在我的父级瀑布对话框中调用
ResumeDialog
。但它显示的是一个 TextPrompt。我很快意识到这是因为在开始子对话框之前我在父对话框的活动步骤中发送了 2 个文本提示。
在开始子对话框之前,我尝试检查父对话框上的堆栈,果然,这两个 TextPrompt 是堆栈中的最后一项,位于我的父瀑布对话框之后。
首先我尝试操作堆栈:
stepContext.Stack.Clear()
- 这也删除了我的父级瀑布,当子级完成时结束了所有对话框。EndDialogAsync
,认为这将正确处理我的 2 个文本提示。这导致了转弯错误。最后我意识到,为了保持简洁,这些文本提示确实属于子瀑布对话框的第一步。当我将它们移到其中时,我最终得到了相同的流程(就最终用户而言),但是当在子瀑布对话框中调用
EndDialogAsync
时,它最终调用了我的父瀑布模型的下一步子瀑布对话框结果作为 stepContext.Result
传入(无需覆盖 ResumeDialogAsync
,如文档所示)。