【问题标题】:Populate Picker with Data using MVVM Xamarin Forms使用 MVVM Xamarin Forms 使用数据填充选取器
【发布时间】:2017-11-16 12:27:13
【问题描述】:

我正在尝试使用选择器来填充数据。在这方面似乎没有一个直接的答案。我已经尝试了很多东西,其中一件事是:

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" };

这很好用,但它只是一个虚拟功能,因为将来这些名称将从某种服务中获取。 因此,为了复制它,我尝试将此列表分离到一个模拟服务中,然后将列表返回到视图模型并使其以这种方式工作。

但这仍然没有返回到前端,即使我在调试时可以看到列表不是空白的。 然后我尝试创建一个 Driver 类并返回其中包含该名称的类的实例并在 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;          

        }

这不起作用,但是当通过调试运行时,它显示驱动程序已填充。 我浪费了很多时间试图完成这项工作,有人有见解吗?

【问题讨论】:

  • 使用 ObservableCollection 代替 List
  • 我会试试这个
  • 你应该做 Drivers.AddRange(...) 而不是 assignment...
  • @RomanAnanyev: 如果您要更新,请致电Clear :-)

标签: c# xaml xamarin mvvm


【解决方案1】:

您需要一个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 的新手
  • 对不起,我的错,这是视图模型。通过BindingContext = new YourViewModel()绑定到视图的那个@
  • 谢谢!另外这如何访问模型类中的数据?
  • 我问是因为稍后这将出去并从服务中获取名称
  • 还是像以前一样调用GetDriverNames方法?
猜你喜欢
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
相关资源
最近更新 更多