Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.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中将listview itemssource设置为viewmodel?_C#_Xamarin_Viewmodel - Fatal编程技术网

C# 如何在Xamarin中将listview itemssource设置为viewmodel?

C# 如何在Xamarin中将listview itemssource设置为viewmodel?,c#,xamarin,viewmodel,C#,Xamarin,Viewmodel,我试图在xamarin中创建一个listview来显示restapi中的数据,但可以选择过滤列表或根据姓氏对其排序 我已经将bindingcontext设置为apiviewmodel,它可以工作。但是我想将itemssource设置为一个列表,以后可以对其进行操作,而不是绑定上下文 以下是有效的代码: Xaml: <ListView x:Name="DirectoryListView" ItemsSource="{Binding ContactsList}" IsPullToRefresh

我试图在xamarin中创建一个listview来显示restapi中的数据,但可以选择过滤列表或根据姓氏对其排序

我已经将bindingcontext设置为apiviewmodel,它可以工作。但是我想将itemssource设置为一个列表,以后可以对其进行操作,而不是绑定上下文

以下是有效的代码:

Xaml:

<ListView x:Name="DirectoryListView" ItemsSource="{Binding ContactsList}" IsPullToRefreshEnabled="True">
APIViewModel.cs:

private List<MainContacts> _ContactsList { get; set; }
public List<MainContacts> ContactsList
    {
        get
        {
            return _ContactsList;
        }
        set
        {
            if(value != _ContactsList)
            {
                _ContactsList = value;
                NotifyPropertyChanged();
            }
        }
    }

public class MainContacts
{
    public int ID { get; set; }
    public string FirstName { get; set; }
}
我想我需要添加这些行,以便我可以操作正在显示的列表。为什么不显示列表?这不是应该做的吗?

将公共列表联系人列表更改为公共可观察收集联系人列表

在xaml.cs中

而不是LocalList=LocalAPIViewModel.ContactsList;,放


我认为这会起作用,而不是根据您的描述和代码将ListView的Itemsource设置为“LocalList”

,您首先使用MVVM绑定ListView,它工作得很好,现在您想使用Viewmodel直接在xaml.cs中绑定ListView Itemsource,对吗

如果是,我根据您的代码做了一个示例,您可以查看,数据可以成功显示

public partial class Page4 : ContentPage
{
    public APIViewModel LocalAPIViewModel { get; set; }
    public Page4 ()
    {
        InitializeComponent ();
        LocalAPIViewModel = new APIViewModel();           
        listview1.ItemsSource = LocalAPIViewModel.ContactsList;
    }
}

public class APIViewModel
{
    public ObservableCollection<MainContacts> ContactsList { get; set; }
    public APIViewModel()
    {
        loadddata();
    }

    public void loadddata()
    {
        ContactsList = new ObservableCollection<MainContacts>();
        for(int i=0;i<20;i++)
        {
            MainContacts p = new MainContacts();
            p.ID = i;
            p.FirstName = "cherry"+i;
            ContactsList.Add(p);
        }
    }
}
public class MainContacts
{
    public int ID { get; set; }
    public string FirstName { get; set; }
}
因此,我建议您可以检查ContactsList是否有数据

更新:

我想能够搜索一个搜索栏列表,也按名字或姓氏排序。我还希望能够点击其中一个联系人,并打开一个关于该联系人的单独页面

我做了一个能满足您要求的样品,您可以看看:

所以,要回答你所有的问题

首先是绑定

一旦您设置了ItemsSource={Binding ContactsList},这意味着无论何时,只要您通过调用OnPropertyChanged来表示您已经更改了ContactsList,就会在ItemsSource属性上反映出来,因此,更新UI-这就是为什么我们将OnPropertyChanged放入setter中的原因。因此,您不需要每次更改ItemsSource时都手动设置它。尤其是在视图中,因为视图应该不知道如何在ViewModel中定义ContactsList

因此,您可以从视图的代码隐藏中完全删除这些行

接下来是排序和搜索

OnPropertyChanged所做的是,它从ViewModel重新请求绑定属性,并根据该属性更新视图。因此,在调用OnPropertyChanged之后,视图将调用绑定属性ContactsList的getter

因此,一个好主意是将排序机制放入公共属性的getter中。或setter,当重置属性时。大概是这样的:

public class ViewModel {
    private ObserveableCollection<MainContacts> contactList { get; set; }
    public ObserveableCollection<MainContacts> ContactList {
        get {
            return new ObservableCollection<MainContacts>(contactList
                .Where(yourFilteringFunc)
                .OrderBy(yourOrderingFunc));
        }
        set {
            contactsList = value;
            OnPropertyChanged();
        }
    }
    //...
}

因此,每当调用公共属性时,它都会对私有属性进行排序,并以这种方式返回集合。

将此行添加到xaml.cs时,我遇到以下错误-ContactsList在当前上下文中不存在,ObservableCollection需要1个类型的参数为什么要添加这些行?它完全违反了MVVM体系结构。此外,基本上是将相同的数据源重新分配给ListView,这没有任何意义。你想实现什么?你可以告诉我,我对这个很陌生。我想能够搜索一个搜索栏列表,也按名字或姓氏排序。我还希望能够单击其中一个联系人并打开关于该联系人的单独页面。@Ryan,我制作了一个可以满足您要求的示例,请查看我的回复更新。@Ryan,您不需要添加这些行,我使用BindingContext来制作可以接受您要求的示例,你可以看看我的更新。谢谢你的回答!请你回顾一下我的原始问题,如果它是好的,那么就投它一票,如果它是坏的,那么让我知道我可以如何改进它!这真的很有帮助!请你看看我原来的问题,如果它是好的,那么就投票给它,如果它是坏的,那么让我知道我可以如何改进它!
ContactsList = new ObservableCollection(LocalAPIViewModel.ContactsList);
public partial class Page4 : ContentPage
{
    public APIViewModel LocalAPIViewModel { get; set; }
    public Page4 ()
    {
        InitializeComponent ();
        LocalAPIViewModel = new APIViewModel();           
        listview1.ItemsSource = LocalAPIViewModel.ContactsList;
    }
}

public class APIViewModel
{
    public ObservableCollection<MainContacts> ContactsList { get; set; }
    public APIViewModel()
    {
        loadddata();
    }

    public void loadddata()
    {
        ContactsList = new ObservableCollection<MainContacts>();
        for(int i=0;i<20;i++)
        {
            MainContacts p = new MainContacts();
            p.ID = i;
            p.FirstName = "cherry"+i;
            ContactsList.Add(p);
        }
    }
}
public class MainContacts
{
    public int ID { get; set; }
    public string FirstName { get; set; }
}
public class ViewModel {
    private ObserveableCollection<MainContacts> contactList { get; set; }
    public ObserveableCollection<MainContacts> ContactList {
        get {
            return new ObservableCollection<MainContacts>(contactList
                .Where(yourFilteringFunc)
                .OrderBy(yourOrderingFunc));
        }
        set {
            contactsList = value;
            OnPropertyChanged();
        }
    }
    //...
}