如何解决FormFlow

时间:2018-04-16 13:18:39

标签: c# botframework formflow

我正在使用带有FormFlow的Microsoft Bot Framework让用户填写表单。 我们说我的表单有两个字段:

  • 国家

所以我有两个枚举:

public enum Country {
    France, Germany
}

public enum City {
    Paris, Berlin
}

字段 City 始终取决于字段 Country ,因为城市属于某个国家/地区。 这意味着用户应该只能填写法国+巴黎德国+柏林

我的表格:

public class LocationForm
{
    [Prompt("Which country? {||}")]
    public Country? Country;

    [Prompt("Which city? {||}")]
    public City? City;
}

我的建设者:

private static IForm<LocationForm> BuildLocationForm()
{
    return new FormBuilder<LocationForm>()
        .Field(nameof(Country))
        .Field(new FieldReflector<LocationForm>(nameof(LocationForm.City))
                .SetDefine(async (state, field) =>
                {
                    switch (state.Country)
                    {
                        case Country.France:
                            field.RemoveValue(City.Berlin);
                            break;
                        case Country.Germany:
                            field.RemoveValue(City.Paris);
                            break;
                    }
                return true;
                })
        .Confirm(async (state) =>
                new PromptAttribute(
                    "You selected {Country} and {City}, is that correct? {||}"))
        .Build();
}

我不知道 RemoveValue 的用法在这里是否正确,感觉有点黑客攻击,但它到目前为止都有效。

用户第一次填写表单时,一切正常,用户只能选择巴黎柏林,具体取决于国家/地区选择之前。 但是,当用户使用回答确认问题时,可以更改国家/地区城市。 当用户随后将国家/地区法国更改为德国时,FormFlow会询问:

  

你选择了德国和巴黎,这是正确的吗?

显然不正确,但仍然可以回答

我希望实现,只要通过确认对话框更改国家/地区,用户就必须更改 City 选项,具体取决于< em>国家字段以及。

我正在玩 SetNext 方法,但我无法找出有用的东西。

我在这里走错了路吗? 如果不破解整个FormFlow实现,这甚至是可能的吗?

我将不胜感激任何帮助!

提前致谢!

更新(附加信息):我尝试过Microsoft发现的三明治机器人示例here并且它似乎有相同(错误)的行为。 订购 Foot Long 三明治时,您可获得额外的(免费饼干/饮料)。在确认之后将长度更改为 Six Inch 您还有额外费用,但只需支付 Six Inch

1 个答案:

答案 0 :(得分:1)

您可以在a - 0 - x a - 0 - y b - 0 - x b - 0 - y c - 0 - x c - 0 - y 字段内验证先前和新选择是否相同;如果它不清楚country的值,那么再次提示城市。

同时将您的城市类型更改为city,以便您可以根据string的选择动态加载值,而不是使用country(虽然这不是一个糟糕的方法)< / p>

所以代码是:

field.RemoveValue()

现在你有了预期的行为。如果国家/地区发生变化,将再次提示城市进行选择。如果用户说[Serializable] public class LocationForm { [Prompt("Which country? {||}")] public Country? country; [Prompt("Which city? {||}")] public string city; public static IForm<LocationForm> BuildLocationForm() { return new FormBuilder<LocationForm>() .Field(new FieldReflector<LocationForm>(nameof(country)) .SetValidate(async (state, response) => { var result = new ValidateResult { IsValid = true, Value = response }; //Validation to check if the current country and previous selected country are same so that user is not prompted again for city if (state.country.ToString() != response.ToString()) state.city = String.Empty; return result; })) .Field(new FieldReflector<LocationForm>(nameof(city)) //To get buttons SetType(null) .SetType(null) .SetDefine(async (state, field) => { //Any previous value before the confirm should be cleared in case selection is changed for country field.RemoveValues(); switch (state.country) { case Country.France: field .AddDescription(nameof(City.Berlin), nameof(City.Berlin)) .AddTerms(nameof(City.Berlin), nameof(City.Berlin)); //Add more description and terms if any break; case Country.Germany: field .AddDescription(nameof(City.Paris), nameof(City.Paris)) .AddTerms(nameof(City.Paris), nameof(City.Paris)); //Add more description and terms if any break; } return true; })) .AddRemainingFields() .Confirm(async (state) => { return new PromptAttribute($"You selected {state.country} and {state.city}, is that correct?" + "{||}"); }) .Build(); } } [Serializable] public enum Country { France, Germany } [Serializable] public enum City { Paris, Berlin } 进行确认并且没有更改国家/地区并选择以前选择的县本身,则不会再次提示城市,直接确认选定的no和{{1提示。

模拟器响应 enter image description here