如何在 Xamarin 中将 listview itemssource 设置为 viewmodel?
How to set listview itemssource to a viewmodel in Xamarin?
我正在尝试在 xamarin 中创建一个列表视图以显示来自 restapi 的数据,但可以选择过滤列表或根据姓氏对其进行排序。
我已将 bindingcontext 设置为等于有效的 apiviewmodel。但是我想将 itemssource 设置为一个可以在以后操作的列表,而不是绑定上下文。
这是有效的代码:
Xaml:
<ListView x:Name="DirectoryListView" ItemsSource="{Binding ContactsList}" IsPullToRefreshEnabled="True">
Xaml.cs:
LocalAPIViewModel = new APIViewModel();
BindingContext = LocalAPIViewModel;
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;
DirectoryListView.ItemsSource = LocalList;
我想我需要添加这些行,以便我可以操作正在显示的列表。为什么不显示列表?这不应该是这样吗?
将public List<MainContacts> ContactsList
更改为public ObservableCollection<MainContacts> ContactsList
在xaml.cs
而不是LocalList = LocalAPIViewModel.ContactsList;
,把
ContactsList = new ObservableCollection(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是否有数据。
更新:
I want to be able to search the list with a search bar and also order it by first or last names. I also want to be able to click on one of the contacts and open up a separate page about that contact
我做了一个样品,可以满足你的要求,你可以看看:
https://github.com/851265601/xf-listview
所以,回答你所有的问题...
首先是绑定。
一旦你设置了 ItemsSource="{Binding ContactsList}"
这意味着任何时候你通过调用 OnPropertyChanged()
发出你已经改变你的 ContactsList
的信号,这将反映在 ItemsSource
属性(因此,更新 UI - 这就是我们将 OnPropertyChanged()
放入 setter 的原因)。因此,您无需在每次更改时手动设置 ItemsSource
。 (特别是从 View 来看,因为 View 应该不知道 ContactsList 是如何在 ViewModel 中定义的。)
So you can completely remove those lines from the View's code-behind.
接下来是排序和搜索。
OnPropertyChanged()
的作用是,它从 ViewModel 重新请求绑定 属性,并据此更新视图。因此,就在 OnPropertyChanged()
被调用之后,绑定 属性 (ContactsList
) 的 getter 被视图调用。
所以,一个好主意是把排序机制放到public属性的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();
}
}
//...
}
因此,无论何时调用 public 属性,它都会以这种方式对私有 属性 和 return 集合进行排序。
我正在尝试在 xamarin 中创建一个列表视图以显示来自 restapi 的数据,但可以选择过滤列表或根据姓氏对其进行排序。
我已将 bindingcontext 设置为等于有效的 apiviewmodel。但是我想将 itemssource 设置为一个可以在以后操作的列表,而不是绑定上下文。
这是有效的代码:
Xaml:
<ListView x:Name="DirectoryListView" ItemsSource="{Binding ContactsList}" IsPullToRefreshEnabled="True">
Xaml.cs:
LocalAPIViewModel = new APIViewModel();
BindingContext = LocalAPIViewModel;
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;
DirectoryListView.ItemsSource = LocalList;
我想我需要添加这些行,以便我可以操作正在显示的列表。为什么不显示列表?这不应该是这样吗?
将public List<MainContacts> ContactsList
更改为public ObservableCollection<MainContacts> ContactsList
在xaml.cs
而不是LocalList = LocalAPIViewModel.ContactsList;
,把
ContactsList = new ObservableCollection(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是否有数据。
更新:
I want to be able to search the list with a search bar and also order it by first or last names. I also want to be able to click on one of the contacts and open up a separate page about that contact
我做了一个样品,可以满足你的要求,你可以看看:
https://github.com/851265601/xf-listview
所以,回答你所有的问题...
首先是绑定。
一旦你设置了 ItemsSource="{Binding ContactsList}"
这意味着任何时候你通过调用 OnPropertyChanged()
发出你已经改变你的 ContactsList
的信号,这将反映在 ItemsSource
属性(因此,更新 UI - 这就是我们将 OnPropertyChanged()
放入 setter 的原因)。因此,您无需在每次更改时手动设置 ItemsSource
。 (特别是从 View 来看,因为 View 应该不知道 ContactsList 是如何在 ViewModel 中定义的。)
So you can completely remove those lines from the View's code-behind.
接下来是排序和搜索。
OnPropertyChanged()
的作用是,它从 ViewModel 重新请求绑定 属性,并据此更新视图。因此,就在 OnPropertyChanged()
被调用之后,绑定 属性 (ContactsList
) 的 getter 被视图调用。
所以,一个好主意是把排序机制放到public属性的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();
}
}
//...
}
因此,无论何时调用 public 属性,它都会以这种方式对私有 属性 和 return 集合进行排序。