我正在使用带有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 。
答案 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提示。