2 回答
TA贡献2051条经验 获得超10个赞
您不必手动编写 Json,还有其他方法可以做到这一点。
首先修改您的QuestionList对象以调用另一个字段,Answer或者您更喜欢调用它。
public class QuestionList
{
public string QuestionLabel { get; set; }
public string QuestionCode { get; set; }
public string Answer { get; set; }
}
这个新属性将保存答案的值。
第二:改变你List<QuestionList>的 ObservableCollection
这里:
private ObservableCollection<QuestionList> survey;
和这里
survey = new ObservableCollection<QuestionList>
{
new QuestionList { QuestionLabel = "Question 1?", QuestionCode = "01" },
new QuestionList { QuestionLabel = "Question 2?", QuestionCode = "02" }
};
稍微改变一下你的 XAML。将 绑定Answer到Picker SelectedItem. 这就是“魔术”发生的地方。
<Picker x:Name="QuestionPicker"
SelectedItem="{Binding Answer, Mode=TwoWay}">
<Picker.Items>
<x:String>Yes</x:String>
<x:String>No</x:String>
</Picker.Items>
</Picker>
每次用户从中选择一个值时,Picker它都会自动更新Answer您设置为的 List 的属性ItemsSource。更多关于绑定在这里
现在您只需更改 Button Clicked 事件,使用这行代码您将拥有一个做得很好的 Json。(首先你需要安装Newtonsoft Nugget)
这里有一个教程,展示了如何安装一个 nugget 包(巧合的是,他们使用相同的库作为示例,我们很幸运!)。
var json = JsonConvert.SerializeObject(survey);
上面将创建一个具有以下格式的 json:
[
{
"QuestionLabel":"Question 1",
"QuestionCode" : "01",
"Answer":"No"
},
{
"QuestionLabel":"Question 2",
"QuestionCode" : "02",
"Answer":"Yes"
},
{
"QuestionLabel":"Question 3",
"QuestionCode" : "03",
"Answer":"Yes"
},
{
"QuestionLabel":"Question 4",
"QuestionCode" : "04",
"Answer":"Yes"
},
{
"QuestionLabel":"Question 5",
"QuestionCode" : "05",
"Answer":"No"
}
]
如您所见,这表示一个 QuestionList 数组,并且您的服务器端点应该期望它作为请求正文。为了清楚起见,我Answer用随机值填充。
整个 Click 事件代码看起来像
void Button_Clicked(object sender, System.EventArgs e)
{
using(var client = new HttpClient())
{
client.BaseAddress = new Uri("http://myip");
var json = JsonConvert.SerializeObject(survey);
var listViewDataContent = new FormUrlEncodedContent(json);
var response = client.PostAsync("/api/GetData", listViewDataContent);
}
}
注意:请注意,我对初始化 HttpClient 的方式进行了一些更改。是的,我知道该文档存在,但是您每次单击按钮时都会创建一个新实例,因为这不是问题的一部分,以免说我们没有看到它。
注意 2:将值与服务器在 json 中的期望值匹配。这里重要的是向您展示使用Xamarin.Forms绑定您可以从中获取值,ListView并且使用Newtownsoft.Json您可以轻松地将数据从C# Object 转换为Json。更多关于这个库的信息在这里。
TA贡献1829条经验 获得超4个赞
好的,所以我解决了,感谢@apineda 和@Andrew,他们将我引导到正确的方向。也许解决方案没有它可以的那么干净,但它确实有效。
第 1 步 - 模型
我有两个班级
调查列表
问题清单
public class SurveyList
{
[JsonProperty("title")]
public string SurveyTtitle { get; set; }
[JsonProperty("questions")]
public List<QuestionList> Questions { get; set; }
}
public class QuestionList
{
[JsonProperty("question")]
public string QuestionText { get; set; }
[JsonProperty("questionId")]
public string QuestionCode { get; set; }
}
第 2 步 - 我的 Xaml
我的 ListView 标题的标题
<ListView.Header>
<StackLayout Padding="0, 30" VerticalOptions="CenterAndExpand">
<Label x:Name="surveyTitle" Text="" FontSize="18" FontAttributes="Bold" HorizontalOptions="Center"/>
</StackLayout>
</ListView.Header>
ListView 项目模板
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="5, 5, 5, 15" VerticalOptions="Start" HorizontalOptions="FillAndExpand">
<Label Text="{Binding QuestionText}"/>
<Picker ItemDisplayBinding="{Binding QuestionCode}" Title="Select Yes or No" FontSize="Small" TextColor="Gray" SelectedIndexChanged="Handle_SelectedIndexChanged">
<Picker.Items>
<x:String>Yes</x:String>
<x:String>No</x:String>
</Picker.Items>
</Picker>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
用于发送数据的按钮的 ListView 页脚
<ListView.Footer>
<StackLayout Padding="0, 30, 0, 30">
<Button x:Name="surveyButton"
Text="Send Survey"
TextColor="White"
BackgroundColor="Teal"
Clicked="Handle_Clicked" />
</StackLayout>
</ListView.Footer>
第 3 步 - 我的 CodeBehind
我添加了参数、IDictionary、baseURI、API 和资源
private IDictionary<string, string> Answers;
private string baseUri = "http://myip";
private string api = "/api";
private string resource = "/GetData";
private string username = "username";
private string password = "password";
在构造函数中,我实例化了 Dictionary 对象
Answers = new Dictionary<string, string>();
添加了一个覆盖 OnAppearing() ,因此每次调用该页面时,它都会调用 API 并检查它们是否有可用的调查(注意:@apineda,抱歉,没有添加您的代码,这更干净,但我已经在编写它了)
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(baseUri);
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password)));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("Application/json"));
var response = client.GetAsync(api).Result;
if (response.IsSuccessStatusCode)
{
var getJson = client.GetStringAsync(api + resource).Result;
var jsonString = JsonConvert.DeserializeObject<SurveyList>(getJson);
surveyTitle.Text = jsonString.SurveyTtitle;
Survey = new List<QuestionList>();
foreach (var surveys in jsonString.Questions)
{
Survey.Add(new QuestionList { QuestionText = surveys.QuestionText, QuestionCode = surveys.QuestionCode });
}
surveyList.ItemsSource = Survey;
surveyList.EndRefresh();
stackButton.IsVisible = true;
}
else
{
surveyTitle.Text = "No Surveys Available";
}
选择器选择索引更改以在每次更改时将值添加到答案字典
void Handle_SelectedIndexChanged(object sender, System.EventArgs e)
{
var picker = sender as Picker;
var item = picker.BindingContext;
var question = item as QuestionList;
Answers.Add(question.QuestionCode, picker.SelectedItem.ToString());
}
发送所有数据的按钮方法
void Handle_Clicked(object sender, System.EventArgs e)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(baseUri);
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password)));
foreach (KeyValuePair<string, string> item in Answers)
{
Dictionary<string, string> collectAnswers = new Dictionary<string, string>()
{
{ item.Key, item.Value }
};
}
var collectAnswersContent = new FormUrlEncodedContent(collectAnswers);
var response = await client.PostAsync(api + "/addSurveyAnswers", collectAnswersContent);
if (response.IsSuccessStatusCode)
{
await DisplayAlert(null, "Thank you for answering the survey", "Close");
(sender as Button).BackgroundColor = Color.FromHex("#00afb9");
}
else
{
await DisplayAlert("Error", "Please Try Again, something went wrong", "OK");
(sender as Button).BackgroundColor = Color.FromHex("#00afb9");
}
}
我知道这段代码不是很干净(Xamarin 和 C# 的新手),只是想发布答案以防有人发现它有用。我违反了程序员法,我在很多地方都在重复自己,但到目前为止它仍然有效,现在我可以开始清理代码了
- 2 回答
- 0 关注
- 175 浏览
添加回答
举报