使用MVVM Xamarin Forms填充选择器的数据

3

我想让一个选择器填充数据,但好像没有一个直截了当的答案。我已经尝试过很多方法,有一种方法可以起作用:

Xaml:

<Picker Grid.Row="2"
           Grid.Column="0"
           Grid.ColumnSpan="4"
           Title="Driver Name"
            ItemsSource="{Binding Drivers}"                
            SelectedItem="{Binding driverID}"

在视图模型中:

List<string> Drivers = new List<string> { "Steve","Dave" };

这很好用,但实际上只是一个仿真功能,因为将来这些名称将从某种服务中获取。 为了模仿这个,我尝试将此列表分离为一个模拟服务,并将列表返回到视图模型,然后使其工作。
但即使在调试时可以看到列表不为空,仍然无法将其返回到前端。 然后我尝试创建一个驱动程序的类,并返回包含名称的类的实例,并在Xaml中访问它。 但这并没有起作用,我甚至尝试使用IList的一个变化,这也行不通。
我不确定为什么不能按预期工作,因为该列表实际上只是被分隔成了另一个类。例如,现在我正在尝试以下内容:
Xaml:
 <Picker Grid.Row="2"
           Grid.Column="0"
           Grid.ColumnSpan="4"
           Title="Driver Name"
            ItemsSource="{Binding Drivers}"                
            SelectedItem="{Binding driverID}"
            />

视图模型:

这个与选择器绑定

public List<string> Drivers;

然后从构造函数中调用此方法:
 public async Task FindDriverNames()
    {
        Drivers = await GetDriverNames();           
    }

在模型中:

 public async Task<List<string>> GetDriverNames()
        {
            await Sleep();

            List<string> _drivers = new List<string> { "Steve"};

            return _drivers;          

        }

这段代码不起作用,但是在调试时显示Drivers已被填充。我浪费了很多时间来尝试让它工作,有没有人有见解?


使用ObservableCollection<string>代替List<string>。 - 3615
我会尝试一下。 - user3355961
你最好使用 Drivers.AddRange(...) 而不是赋值操作符... - Roman Ananyev
@RomanAnanyev:如果你正在更新,请在之前调用Clear函数 :-) - Stefan
1个回答

2
您需要一个ObservableCollection,并且可能需要实现INotifyPropertyChanged接口来通知视图进行任何更改。
public class YourViewModel: INotifyPropertyChanged
{
     public YourViewModel()
     { 
         Drivers = new ObservableCollection<string>();
     }

     private ObservableCollection<string> _drivers;
     public ObservableCollection<string> Drivers
     {
         get { return _drivers; }
         set
         {
            if (Equals(value, _drivers)) return;
            _drivers= value;
            OnPropertyChanged(nameof(Drivers));
         }
     }

     protected virtual void OnPropertyChanged(string propertyName)
     {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
}

通过实现INotifyPropertyChanged接口,您将允许视图在整个列表更改时进行更新。如果向可观察集合添加项目,则可观察集合将通知UI。
正如Roman所指出的那样,在这种特定情况下,您还可以使用可观察集合来更新ui
public async Task FindDriverNames()
{
    Drivers.Clear();
    Drivers.AddRange(await GetDriverNames());           
}

对于其他bound属性,您仍需要使用OnPropertyChanged事件。

请参见ObservableCollection<T>INotifyPropertyChanged


这是为视图模型还是模型? 另外,这个如何访问模型中的数据? 抱歉问题有点多,我是Xamarin新手。 - user3355961
抱歉,我的错,这是视图模型。你可以通过 BindingContext = new YourViewModel() 将其绑定到视图。 - Stefan
谢谢!另外,这个程序如何访问模型类中的数据? - user3355961
我不会在构造函数中调用它,因为这是不好的实践,因为它是一个异步调用,如果抛出异常,则可能很难处理。 - Stefan
OnAppering可能是一个不错的触发器。但要注意,如果有人离开并重新进入应用程序,它也会触发。 - Stefan
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接