xamarin.forms - Xamarin 表单选择器值绑定
问题描述
绑定到选择器时,您可以使用ItemDisplayBinding
绑定显示的值,但我没有看到将每个项目映射到选择值的方法。因此,我不得不编写一些非常复杂的代码来使我的选择器与数据源更改保持同步。
原始模型
// NOTE: this implements INPC, just abbreviated for clarity
public class DataModel
{
public ICollection<DataItem> Items;
pubilc DataItem SelectedItem;
}
原始选择器:
<Picker Title="Select Item..."
ItemsSource="{Binding Items}"
ItemDisplayBinding="{Binding Name}"
SelectedItem="{Binding Path=SelectedItem}"></Picker>
新模式
// NOTE: this implements INPC, just abbreviated for clarity
public class DataModel
{
public ICollection<DataItems> Items;
public ICollection<string> ItemNames;
public DataItem SelectedItem;
public string SelectedItemName;
public DataModel()
{
this.PropertyChanged += (s, e) =>
{
// I feel like I shouldn't have to do this...
if(StringComparer.Ordinal.Equals(e.PropertyName, nameof(Items)))
{
if(!String.IsNullOrWhitespace(this.SelectedItemName))
{
this.SelectedItem = this.Items.FirstOrDefault(x => StringComparer.Ordinal.Equals(x.Name, this.SelectedItemName));
if (this.SelectedItem == null) { this.SelectedItemName = null; }
}
}
}
}
新选择器:
<Picker Title="Select Item..."
ItemsSource="{Binding ItemNames}"
SelectedItem="{Binding Path=SelectedItemName}"></Picker>
我希望能够做这样的事情:
<Picker Title="Select Item..."
ItemsSource="{Binding Items}"
ItemDisplayBinding="{Binding Name}"
ItemValueBinding="{Binding Name}"
SelectedItem="{Binding Path=SelectedItemName}"></Picker>
我不需要对该项目的引用,我需要它的属性。这样,当 Items 集合更改时,如果它仍然存在,它会自动重新选择正确的项目。我发现我正在到处添加第二个集合,其中只有我想要选择的属性并执行所有这些映射。我工作过的所有其他平台,这很简单,所以我觉得我必须在 Xamarin.Forms 上遗漏一些东西。
解决方案
我认为您不需要这样做。SelectedItem 属性数据绑定到已连接视图模型的 SelectedItem(在您的原始模型中)属性,该属性是 DataItem 类型。因此,当用户在 Picker 中选择一个项目时,SelectedItem 属性将自动设置为选定的 DataItem 对象。
您可以在其SelectedIndexChanged
事件中对其进行测试,例如:
<Picker Title="Select Item..."
ItemsSource="{Binding Items}"
ItemDisplayBinding="{Binding Name}"
SelectedItem="{Binding Path=SelectedItem}"
SelectedIndexChanged="Picker_SelectedIndexChanged">
</Picker>
private void Picker_SelectedIndexChanged(object sender, EventArgs e)
{
Picker picker = sender as Picker;
DataItem dt = picker.SelectedItem as DataItem ;
Console.WriteLine(dt.Name); // you will see when you select a item,the SelectedItem will be changed automatically
}
我建议你使用 ObservableCollection<Item> Items
,所以Items
当它改变时它会自动更新你。
推荐阅读
- typescript - 使用 Chart.js 绘制方法作为 Typescript 箭头函数
- c++ - 如何在另一个 c++ 文件中声明 Paho MQTT C++?
- karate - 在空手道框架中,无法通过解析获取 xml 响应中的值
- sql-server - 合并一列,同时对具有相似值的另一列进行分组
- r - 使用 R 中另一个表的范围内的表中的点连接
- c# - C# Memoization 方法在返回函数后如何保留缓存
- spring - Spring Boot 自定义启动器和 Spring Data JPA - 如何在我自己的自定义自动配置/启动器模块上正确提供存储库
- c# - C# 电报机器人收到“对 SSPI 的调用失败”错误
- java - 为什么当我们有自定义实现时,Java 不强制我们重写 equals 和 hashcode
- rust - 有没有一种优雅的方式来使用“match”语句重写获取或创建选项?