是否可以获取当前对话步骤名称?
Is it possible to get the current dialog step name?
我正在编写一个机器人,我想创建一个分步帮助系统。我设置了一个字典,允许每个对话框覆盖其中每个步骤的帮助文本:
public abstract class BaseDialog : ComponentDialog
{
private static Dictionary<string, string> StepHelp = new Dictionary<string, string>();
protected static void AddStepHelp(string function, string text)
{
StepHelp.Add(function, text);
}
private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken)
{
Activity helpMessage;
string curStepName = ""; //???
if (userText == "help" && StepHelp.ContainsKey(curStepName))
{
helpMessage = MessageFactory.Text(StepHelp[curStepName], StepHelp[curStepName], InputHints.ExpectingInput);
}
await innerDc.Context.SendActivityAsync(helpMessage, cancellationToken);
}
}
然后我在 chidl 对话框中添加文本:
public class MyChildDialog: BaseDialog
{
static MyChildDialog()
{
AddStepHelp(nameof(Step1), "Help text for step1");
}
public MyChildDialog()
{
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
Step1
}));
InitialDialogId = nameof(WaterfallDialog);
}
private async Task<DialogTurnResult> Step1(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
}
}
在上面的InterruptAsync函数中可以看到我调用了字典来获取基本对话框中的帮助信息,但是如何获取当前步骤名称呢?
您可以获得当前步骤 index 以及对话框名称,因此您应该能够从该信息创建一个唯一标识符(只要您没有像我一样为示例中的所有对话框命名 "waterfallDialog"!)。我正在使用节点,但我假设从您的 stepContext 获取数据是相似或相同的。
- 对话框名称可以在
stepContext.stack[stepContext.stack.length-1].id
找到。
- 可在
stepContext.stack[stepContext.stack.length-1].state.stepIndex
处找到步骤索引。
我不记得您是否可以在瀑布对话框中使用嵌套对话框。我知道您的 main/outer 上下文将包含整个堆栈,但我 认为 您将始终只有特定瀑布中的一个元素。也就是说,当前对话框应该是堆栈中的最后一个,因此在任何一种情况下都可以将其作为 stepContext.stack.length-1
访问。如果当前对话框位于元素 0,显然您可以直接访问它。
只要您的瀑布对话框名称是唯一的,您最终会得到诸如 waterfallDialog0、waterfallDialog1 等标识符,然后您可以将其映射到字典中以帮助文本。
我想到您可能正试图从瀑布对话框外部访问它。在那种情况下,您仍然应该能够从外部对话上下文中获取它。您可能必须使用递归函数来获取它,例如
getInnermostActiveDialog(dc) {
var child = dc.child;
return child ? this.getInnermostActiveDialog(child) : dc.activeDialog;
}
其中 dc
是您的外部对话上下文。我没有深入探讨,但你应该能够获得相同的 id
和 stepIndex
值。
虽然如 billoverton 所述,获取步骤索引很容易,但获取步骤名称却很困难。 _steps
field is private and so is the method that returns the step name 因此即使您的 class 派生自 WaterfallDialog
,您也无法访问这些步骤。步骤名称仅通过遥测客户端公开,因此您可以考虑编写一个自定义遥测客户端,以某种方式将信息公开给您的机器人,但此时使用反射访问私有成员可能更容易。
由于您真的只想将步骤名称用作字典的键,因此只使用步骤索引是一个更好的选择。您可以使用 Dictionary<int, string>
,但如果您打算为瀑布中的每个步骤提供帮助字符串,则使用 List<string>
是有意义的。
我正在编写一个机器人,我想创建一个分步帮助系统。我设置了一个字典,允许每个对话框覆盖其中每个步骤的帮助文本:
public abstract class BaseDialog : ComponentDialog
{
private static Dictionary<string, string> StepHelp = new Dictionary<string, string>();
protected static void AddStepHelp(string function, string text)
{
StepHelp.Add(function, text);
}
private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken)
{
Activity helpMessage;
string curStepName = ""; //???
if (userText == "help" && StepHelp.ContainsKey(curStepName))
{
helpMessage = MessageFactory.Text(StepHelp[curStepName], StepHelp[curStepName], InputHints.ExpectingInput);
}
await innerDc.Context.SendActivityAsync(helpMessage, cancellationToken);
}
}
然后我在 chidl 对话框中添加文本:
public class MyChildDialog: BaseDialog
{
static MyChildDialog()
{
AddStepHelp(nameof(Step1), "Help text for step1");
}
public MyChildDialog()
{
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
Step1
}));
InitialDialogId = nameof(WaterfallDialog);
}
private async Task<DialogTurnResult> Step1(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
}
}
在上面的InterruptAsync函数中可以看到我调用了字典来获取基本对话框中的帮助信息,但是如何获取当前步骤名称呢?
您可以获得当前步骤 index 以及对话框名称,因此您应该能够从该信息创建一个唯一标识符(只要您没有像我一样为示例中的所有对话框命名 "waterfallDialog"!)。我正在使用节点,但我假设从您的 stepContext 获取数据是相似或相同的。
- 对话框名称可以在
stepContext.stack[stepContext.stack.length-1].id
找到。 - 可在
stepContext.stack[stepContext.stack.length-1].state.stepIndex
处找到步骤索引。
我不记得您是否可以在瀑布对话框中使用嵌套对话框。我知道您的 main/outer 上下文将包含整个堆栈,但我 认为 您将始终只有特定瀑布中的一个元素。也就是说,当前对话框应该是堆栈中的最后一个,因此在任何一种情况下都可以将其作为 stepContext.stack.length-1
访问。如果当前对话框位于元素 0,显然您可以直接访问它。
只要您的瀑布对话框名称是唯一的,您最终会得到诸如 waterfallDialog0、waterfallDialog1 等标识符,然后您可以将其映射到字典中以帮助文本。
我想到您可能正试图从瀑布对话框外部访问它。在那种情况下,您仍然应该能够从外部对话上下文中获取它。您可能必须使用递归函数来获取它,例如
getInnermostActiveDialog(dc) {
var child = dc.child;
return child ? this.getInnermostActiveDialog(child) : dc.activeDialog;
}
其中 dc
是您的外部对话上下文。我没有深入探讨,但你应该能够获得相同的 id
和 stepIndex
值。
虽然如 billoverton 所述,获取步骤索引很容易,但获取步骤名称却很困难。 _steps
field is private and so is the method that returns the step name 因此即使您的 class 派生自 WaterfallDialog
,您也无法访问这些步骤。步骤名称仅通过遥测客户端公开,因此您可以考虑编写一个自定义遥测客户端,以某种方式将信息公开给您的机器人,但此时使用反射访问私有成员可能更容易。
由于您真的只想将步骤名称用作字典的键,因此只使用步骤索引是一个更好的选择。您可以使用 Dictionary<int, string>
,但如果您打算为瀑布中的每个步骤提供帮助字符串,则使用 List<string>
是有意义的。