Xamarin Forms - 用于延迟加载的绑定列表视图
Xamarin Forms - Binding Listview for lazy loading
开始涉足 Xamarin Forms。
两件事我想不通:
绑定我的列表视图:
我有一个 class 有:
public class Mainlist
{
public string Title
{
get;
set;
}
public string Value
{
get;
set;
}
}
我的 XAML 看起来像:
<ListView x:Name="mainlist">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<StackLayout Orientation="Vertical">
<Label Text="{Binding Title}" Font="18"></Label>
<Label Text="{Binding Value}" TextColor="Gray"></Label>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
现在我有一个 URLS 的列表。从每个 URL 我都在使用 HTMLAgilityPack foreach 循环抓取某些信息,它工作正常。
我想在每个 运行 循环后将抓取的数据添加到列表视图并显示。类似于 "lazy loading"。
到目前为止,我只能弄清楚如何在抓取所有 Urls 后设置 itemsource 并让它立即显示,如下所示:
//set itemsource to URL collection
mainlist.ItemsSource = new List<Mainlist>() {
new Mainlist()
{
//scraped info from each URL
Title = title.ToString().Trim(),
Value = value.ToString().Trim(),
},
};
我想你可以这样做:
mainlist.ItemsSource = new ObservableCollection<Mainlist>();
foreach (var item in yourDataFromHtmlAgilityPackScraping) {
mainlist.ItemsSource.Add(new Mainlist()
{
//scraped info from each URL
Title = item.title.ToString().Trim(),
Value = item.value.ToString().Trim(),
});
}
这里的重要部分是 ObservableCollection。这允许在添加新元素时更新 Listview。
首先,创建一个视图模型class,名为MyViewModel.cs:
public class MyViewModel : INotifyPropertyChanged
{
// property changed event handler
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<Mainlist> _list;
public ObservableCollection<Mainlist> List
{
get { return _list; }
set
{
_list = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(List)));
}
}
public MyViewModel()
{
_list = new ObservableCollection<Mainlist>();
}
public async void StartScraping()
{
// assuming you are 'awaiting' the results of your scraping method...
foreach (...)
{
await ... scrape a web page ...
var newItem = new Mainlist()
{
Title = title.ToString().Trim(),
Value = value.ToString().Trim()
};
// if you instead have multiple items to add at this point,
// then just create a new List<Mainlist>, add your items to it,
// then add that list to the ObservableCollection List.
Device.BeginInvokeOnMainThread(() =>
{
List.Add(newItem);
});
}
}
}
现在在您页面的 xaml.cs
代码隐藏文件中,将视图模型设置为您的 BindingContext
:
public class MyPage : ContentPage // (assuming the page is called "MyPage" and is of type ContentPage)
{
MyViewModel _viewModel;
public MyPage()
{
InitializeComponent();
_viewModel = new MyViewModel();
BindingContext = _viewModel;
// bind the view model's List property to the list view's ItemsSource:
mainList.setBinding(ListView.ItemsSourceProperty, "List");
}
}
请注意,在您的视图模型中,您需要使用 ObservableCollection<T>
而不是 List<T>
,因为 ObservableCollection<T>
将允许 ListView
每当您在其中添加或删除项目时自动更新。
此外,为了减少一些混乱,我建议将 class 名称从 Mainlist
更改为 MainListItem
。
开始涉足 Xamarin Forms。 两件事我想不通:
绑定我的列表视图:
我有一个 class 有:
public class Mainlist
{
public string Title
{
get;
set;
}
public string Value
{
get;
set;
}
}
我的 XAML 看起来像:
<ListView x:Name="mainlist">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<StackLayout Orientation="Vertical">
<Label Text="{Binding Title}" Font="18"></Label>
<Label Text="{Binding Value}" TextColor="Gray"></Label>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
现在我有一个 URLS 的列表。从每个 URL 我都在使用 HTMLAgilityPack foreach 循环抓取某些信息,它工作正常。
我想在每个 运行 循环后将抓取的数据添加到列表视图并显示。类似于 "lazy loading"。
到目前为止,我只能弄清楚如何在抓取所有 Urls 后设置 itemsource 并让它立即显示,如下所示:
//set itemsource to URL collection
mainlist.ItemsSource = new List<Mainlist>() {
new Mainlist()
{
//scraped info from each URL
Title = title.ToString().Trim(),
Value = value.ToString().Trim(),
},
};
我想你可以这样做:
mainlist.ItemsSource = new ObservableCollection<Mainlist>();
foreach (var item in yourDataFromHtmlAgilityPackScraping) {
mainlist.ItemsSource.Add(new Mainlist()
{
//scraped info from each URL
Title = item.title.ToString().Trim(),
Value = item.value.ToString().Trim(),
});
}
这里的重要部分是 ObservableCollection。这允许在添加新元素时更新 Listview。
首先,创建一个视图模型class,名为MyViewModel.cs:
public class MyViewModel : INotifyPropertyChanged
{
// property changed event handler
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<Mainlist> _list;
public ObservableCollection<Mainlist> List
{
get { return _list; }
set
{
_list = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(List)));
}
}
public MyViewModel()
{
_list = new ObservableCollection<Mainlist>();
}
public async void StartScraping()
{
// assuming you are 'awaiting' the results of your scraping method...
foreach (...)
{
await ... scrape a web page ...
var newItem = new Mainlist()
{
Title = title.ToString().Trim(),
Value = value.ToString().Trim()
};
// if you instead have multiple items to add at this point,
// then just create a new List<Mainlist>, add your items to it,
// then add that list to the ObservableCollection List.
Device.BeginInvokeOnMainThread(() =>
{
List.Add(newItem);
});
}
}
}
现在在您页面的 xaml.cs
代码隐藏文件中,将视图模型设置为您的 BindingContext
:
public class MyPage : ContentPage // (assuming the page is called "MyPage" and is of type ContentPage)
{
MyViewModel _viewModel;
public MyPage()
{
InitializeComponent();
_viewModel = new MyViewModel();
BindingContext = _viewModel;
// bind the view model's List property to the list view's ItemsSource:
mainList.setBinding(ListView.ItemsSourceProperty, "List");
}
}
请注意,在您的视图模型中,您需要使用 ObservableCollection<T>
而不是 List<T>
,因为 ObservableCollection<T>
将允许 ListView
每当您在其中添加或删除项目时自动更新。
此外,为了减少一些混乱,我建议将 class 名称从 Mainlist
更改为 MainListItem
。