C# 如何在Xamarin中将listview itemssource设置为viewmodel?
我试图在xamarin中创建一个listview来显示restapi中的数据,但可以选择过滤列表或根据姓氏对其排序 我已经将bindingcontext设置为apiviewmodel,它可以工作。但是我想将itemssource设置为一个列表,以后可以对其进行操作,而不是绑定上下文 以下是有效的代码: Xaml: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
<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();
}
}
//...
}