使用命令加载页面时填充 ListView (Xamarin.Forms)

Est*_*bel 3 .net c# mvvm xamarin xamarin.forms

我尝试在加载页面时填充绑定到 ObservableCollection 的 ListView 失败。目前,我使用以下代码使用按钮(绑定到命令)。

看法:

<Button Text="Load Items" Command="{Binding LoadItemsCommand}"></Button>
<ActivityIndicator IsRunning="{Binding IsBusy}" IsVisible="{Binding IsBusy}" />
<ScrollView>
  <ListView ItemsSource="{Binding Items}">      
    .....
  </ListView>
</ScrollView>
Run Code Online (Sandbox Code Playgroud)

查看.cs:

private ItemsViewModel _itemsViewModel;

public ItemsView()
{
    InitializeComponent();
    _itemsViewModel = new ItemsViewModel();
    BindingContext = _itemsViewModel;
}
Run Code Online (Sandbox Code Playgroud)

视图模型:

public ObservableCollection<Item> Items{ get; set; }
public Command LoadItemsCommand { get; set; }

public ItemsViewModel()
{
    Items = new ObservableCollection<Item>();
    _isBusy = false;

    LoadItemsCommand = new Command(async () => await LoadItems(), () => !IsBusy);    
}

public async Task LoadItems()
{
    if (!IsBusy)
    {
        IsBusy = true;
        await Task.Delay(3000); 
        var loadedItems = ItemsService.LoadItemsDirectory(); 

        foreach (var item in loadedItems)
            Items.Add(item);

        IsBusy = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

这与按钮完美配合,但我不知道如何自动执行。我尝试将列表视图的 RefreshCommand 属性绑定到我的命令,但没有。

Jim*_*ett 7

有几种方法,但最好的方法是在加载数据的视图模型构造函数中启动一项任务。我也不会将每个项目添加到 observable 集合中,因为这意味着最终添加时会更新 UI。加载所有数据后,最好完全替换集合。

就像是:

public ItemsViewModel()
{
    Items = new ObservableCollection<Item>();
    _isBusy = false;

    Task.Run(async () => await LoadItems());    
}

public async Task LoadItems()
{
    var items = new ObservableCollection<Item>(); // new collection

    if (!IsBusy)
    {
        IsBusy = true;
        await Task.Delay(3000); 
        var loadedItems = ItemsService.LoadItemsDirectory(); 

        foreach (var item in loadedItems)
            items.Add(item);                // items are added to the new collection    

        Items = items;   // swap the collection for the new one
        RaisePropertyChanged(nameof(Items)); // raise a property change in whatever way is right for your VM

        IsBusy = false;
    }
}
Run Code Online (Sandbox Code Playgroud)