Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用命令加载页面(Xamarin.Forms)时填充ListView_C#_.net_Mvvm_Xamarin_Xamarin.forms - Fatal编程技术网

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

C# 使用命令加载页面(Xamarin.Forms)时填充ListView,c#,.net,mvvm,xamarin,xamarin.forms,C#,.net,Mvvm,Xamarin,Xamarin.forms,我尝试在加载页面时填充绑定到ObservableCollection的ListView失败。目前,我有一个按钮(绑定到命令)和以下代码 视图: 视图模型: public ObservableCollection<Item> Items{ get; set; } public Command LoadItemsCommand { get; set; } public ItemsViewModel() { Items = new ObservableCollection<

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

视图:

视图模型:

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;
    }
}
publicobservableCollection项{get;set;}
公共命令LoadItemsCommand{get;set;}
public ItemsViewModel()
{
Items=新的ObservableCollection();
_isBusy=false;
LoadItemsCommand=new命令(异步()=>await LoadItems(),()=>!IsBusy);
}
公共异步任务LoadItems()
{
如果(!正忙)
{
IsBusy=true;
等待任务。延迟(3000);
var loadedItems=ItemsService.LoadItemsDirectory();
foreach(loadedItems中的var项)
项目。添加(项目);
IsBusy=false;
}
}

这与按钮完美配合,但我不知道如何自动完成。我尝试将listview的RefreshCommand属性绑定到我的命令,但没有绑定任何内容。

有几种方法,但最好的方法是在视图模型构造函数中启动加载数据的任务。我也不会将每个项目添加到可观察的集合中,因为这意味着在添加结束时进行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;
    }
}
public ItemsViewModel()
{
Items=新的ObservableCollection();
_isBusy=false;
运行(async()=>await LoadItems());
}
公共异步任务LoadItems()
{
var items=newobserveCollection();//新集合
如果(!正忙)
{
IsBusy=true;
等待任务。延迟(3000);
var loadedItems=ItemsService.LoadItemsDirectory();
foreach(loadedItems中的var项)
items.Add(item);//项被添加到新集合中
Items=Items;//将集合交换为新集合
RaisePropertyChanged(nameof(Items));//以适合您的VM的任何方式引发属性更改
IsBusy=false;
}
}

感谢您的帮助@JimBobBennet。它通过在视图模型的构造函数上启动任务来工作。但是,集合的交换不起作用,它只在我将项直接添加到循环中的公共项属性时起作用。另外,我的印象是没有必要调用ObservableCollections上的PropertyChanged。在我的例子中,如果您添加到现有集合,则UI将更新,但速度会很慢,因为UI将为您添加的每个项目重新绘制。对于1000件物品,你会有一段不愉快的时光。属性更改是因为在我的示例中,它用一个全新的集合替换了
Items
属性的值,因此您需要进行属性更改,以告诉它重新加载新集合-导致1个UI updateGot it!谢谢你的澄清@JimBobBennett谢谢@JimBobBennett,它对我也很有效。非常感谢。RaisePropertyChanged有点混乱,如果您可以共享它的实现或引用它所在的类,那就太好了
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;
    }
}
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;
    }
}