ListView 交互性
Xamarin.FormsListView
类支持用户与它呈现的数据进行交互。
选择和点击
ListView
选择模式是通过将 ListView.SelectionMode
属性设置为 ListViewSelectionMode
枚举的值来控制的:
当用户点击某个项时,将触发两个事件:
ItemSelected
在选择某个新项时触发。ItemTapped
在点击某个项时触发。
点击同一个项两次将触发两个 ItemTapped
事件,但只会触发一个 ItemSelected
事件。
注意
ItemTappedEventArgs
类包含 ItemTapped
事件的事件参数,具有 Group
和 Item
属性,以及 ItemIndex
属性,其值表示被点击项的 ListView
中的索引。 同样,SelectedItemChangedEventArgs
类包含 ItemSelected
事件的事件参数,具有 SelectedItem
属性,以及 SelectedItemIndex
属性,其值表示选定项的 ListView
中的索引。
当属性 SelectionMode
设置为 Single
时,可以选择 ListView
中的项,ItemSelected
和 ItemTapped
事件将触发,SelectedItem
属性将设置为所选项的值。
当 SelectionMode
属性设置为 None
时,无法选择 ListView
中的项,ItemSelected
事件将不会触发,SelectedItem
属性将保持为 null
。 但是,仍将触发 ItemTapped
事件,被点击的项将在点击期间短暂突出显示。
选择了某个项且 SelectionMode
属性从 Single
更改为 None
后,SelectedItem
属性将设置为 null
,ItemSelected
事件将与 null
项一起触发。
以下屏幕截图显示了 ListView
和默认选择模式:
禁用选择
若要禁用 ListView
选择,请将 SelectionMode
属性设置为 None
:
<ListView ... SelectionMode="None" />
var listView = new ListView { ... SelectionMode = ListViewSelectionMode.None };
上下文操作
通常,用户希望对 ListView
中的项执行操作。 例如,想一想邮件应用中的电子邮件列表。 在 iOS 上,可以轻扫以删除邮件:
上下文操作可以在 C# 和 XAML 中实现。 在下面你将找到两者的特定指南,但首先让我们看看它们的一些关键实现细节。
上下文操作是使用 MenuItem
元素创建的。 MenuItems
对象的点击事件是由 MenuItem
本身引发的,而不是 ListView
。 这不同于单元格的点击事件的处理方式,其中 ListView
会引发事件而不是单元格。 由于 ListView
引发事件,因此其事件处理程序会获得关键信息,例如已选择或点击了哪个项。
默认情况下,MenuItem
无法知道它所属的单元格。 CommandParameter
属性在 MenuItem
上可用,用于存储对象,例如 MenuItem
的 ViewCell
背后的对象。 可以在 XAML 和 C# 中设置 CommandParameter
属性。
XAML
MenuItem
元素可以在 XAML 集合中创建。 下面的 XAML 演示了一个实现两个上下文操作的自定义单元格:
<ListView x:Name="ContextDemoList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Clicked="OnMore"
CommandParameter="{Binding .}"
Text="More" />
<MenuItem Clicked="OnDelete"
CommandParameter="{Binding .}"
Text="Delete" IsDestructive="True" />
</ViewCell.ContextActions>
<StackLayout Padding="15,0">
<Label Text="{Binding title}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
在代码隐藏文件中,确保实现 Clicked
方法:
public void OnMore (object sender, EventArgs e)
{
var mi = ((MenuItem)sender);
DisplayAlert("More Context Action", mi.CommandParameter + " more context action", "OK");
}
public void OnDelete (object sender, EventArgs e)
{
var mi = ((MenuItem)sender);
DisplayAlert("Delete Context Action", mi.CommandParameter + " delete context action", "OK");
}
注意
适用于 Android 的 NavigationPageRenderer
有可替代的 UpdateMenuItemIcon
方法,可以用来从自定义的 Drawable
加载图标。 使用此替代方法可以将 SVG 图像用作 Android 中 MenuItem
实例上的图标。
代码
上下文操作可以在任何 Cell
子类中实现(只要它不用作组标头),方法是创建 MenuItem
实例并将其添加到单元格的 ContextActions
集合中。 可以为上下文操作配置以下属性:
- Text – 菜单项中显示的字符串。
- Clicked – 单击项时的事件。
- IsDestructive –(可选)为 true 时在 iOS 上以不同方式呈现。
可以将多个上下文操作添加到单元格,但只应有一个操作将 IsDestructive
设置为 true
。 以下代码演示如何将上下文操作添加到 ViewCell
:
var moreAction = new MenuItem { Text = "More" };
moreAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
moreAction.Clicked += async (sender, e) =>
{
var mi = ((MenuItem)sender);
Debug.WriteLine("More Context Action clicked: " + mi.CommandParameter);
};
var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true }; // red background
deleteAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
deleteAction.Clicked += async (sender, e) =>
{
var mi = ((MenuItem)sender);
Debug.WriteLine("Delete Context Action clicked: " + mi.CommandParameter);
};
// add to the ViewCell's ContextActions property
ContextActions.Add (moreAction);
ContextActions.Add (deleteAction);
下拉以刷新
用户已经习惯于下拉数据列表就会刷新该列表。 ListView
控件直接支持此功能。 若要启用拉动刷新功能,请将 IsPullToRefreshEnabled
设置为 true
:
<ListView ...
IsPullToRefreshEnabled="true" />
等效 C# 代码如下:
listView.IsPullToRefreshEnabled = true;
刷新期间会显示一个旋转器,默认为黑色。 但是,通过将 RefreshControlColor
属性设置为 Color
,可以在 iOS 和 Android 上更改旋转器颜色:
<ListView ...
IsPullToRefreshEnabled="true"
RefreshControlColor="Red" />
等效 C# 代码如下:
listView.RefreshControlColor = Color.Red;
以下屏幕截图显示拉动刷新,用户正在拉动:
以下屏幕截图显示用户释放拉动后的拉动刷新,其中显示了旋转器,而 ListView
正在更新:
ListView
会触发 Refreshing
事件以启动刷新,而 IsRefreshing
属性将设置为 true
。 刷新 ListView
的内容所需的任何代码应进而由 Refreshing
事件的事件处理程序执行,或由 RefreshCommand
执行的方法执行。 ListView
刷新后,IsRefreshing
属性应设置为 false
,或应调用 EndRefresh
方法,以指示刷新已完成。
注意
定义 RefreshCommand
时,可以指定命令的 CanExecute
方法以启用或禁用该命令。
检测滚动
ListView
定义 Scrolled
事件,它触发时指示发生了滚动。 以下 XAML 示例显示为 Scrolled
事件设置事件处理程序的 ListView
:
<ListView Scrolled="OnListViewScrolled">
...
</ListView>
等效 C# 代码如下:
ListView listView = new ListView();
listView.Scrolled += OnListViewScrolled;
在此代码示例中,Scrolled
事件触发时,将执行 OnListViewScrolled
事件处理程序:
void OnListViewScrolled(object sender, ScrolledEventArgs e)
{
Debug.WriteLine("ScrollX: " + e.ScrollX);
Debug.WriteLine("ScrollY: " + e.ScrollY);
}
OnListViewScrolled
事件处理程序会输出伴随该事件的 ScrolledEventArgs
对象的值。