You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ListView下Picker的SelectedItem值存入数组?(Xamarin)

问题分析与解决方案

问题根源

你遇到的核心问题是:每个GPADetails实例的SelectedUnit属性在赋值时,没有操作同一个共享的数组实例,反而可能每次都重新创建数组,或者每个实例持有独立的数组引用,导致之前的索引值被覆盖为null。


解决方案1:通过委托实现数据同步(解耦推荐)

这种方式让GPADetails无需直接持有数组引用,通过委托将选中值传递给ViewModel统一维护数组,更符合MVVM解耦原则。

1. 调整GPADetails类

添加一个委托属性,用于通知外部更新数组:

public class GPADetails : INotifyPropertyChanged
{
    private string _selectedUnit;
    public int TemplateID { get; set; }
    public ObservableRangeCollection<string> UnitList { get; set; }
    // 委托:传递TemplateID和选中值给外部处理
    public Action<int, string> OnSelectedUnitChanged { get; set; }

    public string SelectedUnit
    {
        get => _selectedUnit;
        set
        {
            if (_selectedUnit != value)
            {
                _selectedUnit = value;
                OnPropertyChanged(nameof(SelectedUnit));
                // 触发委托,同步更新数组
                OnSelectedUnitChanged?.Invoke(TemplateID, value);
            }
        }
    }

    // INotifyPropertyChanged实现
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 在ViewModel中维护共享数组并绑定委托

ViewModel初始化时创建全局数组,并为每个GPADetails实例绑定委托:

public class GPAViewModel : INotifyPropertyChanged
{
    private string[] _selectedUnitsArray;
    public ObservableRangeCollection<GPADetails> GPADetailsList { get; set; }

    public GPAViewModel(int courseCount)
    {
        // 初始化数组,长度与课程数量一致
        _selectedUnitsArray = new string[courseCount];
        GPADetailsList = new ObservableRangeCollection<GPADetails>();

        // 生成对应数量的课程项
        for (int i = 0; i < courseCount; i++)
        {
            var gpaItem = new GPADetails
            {
                TemplateID = i,
                UnitList = new ObservableRangeCollection<string> { "A", "B", "C", "D", "F" },
                // 绑定委托:更新共享数组
                OnSelectedUnitChanged = (id, value) => 
                {
                    if (id >= 0 && id < _selectedUnitsArray.Length)
                        _selectedUnitsArray[id] = value;
                }
            };
            GPADetailsList.Add(gpaItem);
        }
    }

    // INotifyPropertyChanged实现省略
}

解决方案2:通过事件监听实现数据同步

如果不想用委托,也可以在ViewModel中监听每个GPADetails实例的PropertyChanged事件,主动更新数组:

ViewModel代码调整

public GPAViewModel(int courseCount)
{
    _selectedUnitsArray = new string[courseCount];
    GPADetailsList = new ObservableRangeCollection<GPADetails>();

    for (int i = 0; i < courseCount; i++)
    {
        var gpaItem = new GPADetails
        {
            TemplateID = i,
            UnitList = new ObservableRangeCollection<string> { "A", "B", "C", "D", "F" }
        };
        // 监听每个项的属性变化事件
        gpaItem.PropertyChanged += GpaItem_PropertyChanged;
        GPADetailsList.Add(gpaItem);
    }
}

private void GpaItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == nameof(GPADetails.SelectedUnit))
    {
        var item = sender as GPADetails;
        if (item != null && item.TemplateID >= 0 && item.TemplateID < _selectedUnitsArray.Length)
        {
            _selectedUnitsArray[item.TemplateID] = item.SelectedUnit;
        }
    }
}

关键注意事项

  1. 必须使用共享数组实例:确保所有GPADetails实例操作的是同一个数组,而非各自创建新数组。
  2. 索引边界检查:更新数组时要判断TemplateID是否在数组索引范围内,避免越界异常。
  3. MVVM原则:尽量让GPADetails只负责自身属性维护,数据收集逻辑交给ViewModel处理,降低耦合。

内容的提问来源于stack exchange,提问作者Samuel Mbah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 12:21:12