第十九章:集合视图(十四)

简介:

上下文菜单
单元格可以定义以特定于平台的方式调用的上下文菜单。 这样的上下文菜单通常允许用户对ListView中的特定项执行操作。 例如,当与显示学生的ListView一起使用时,这样的上下文菜单允许用户对特定学生执行动作。
CellContextMenu程序演示了这种技术。 它定义了一个包含四个项的上下文菜单:

  • 重置GPA(将学生的平均成绩设置为2.5)
  • 移至顶部(将学生移至列表顶部)
  • 移动到底部(类似地将学生移到底部)
  • 删除(从列表中删除学生)

在iOS上,通过向左滑动项目来调用上下文菜单。 在Android和Windows 10 Mobile上,您将手指按到该项目并按住它直到出现菜单。 这是结果:
201811041450040426
iOS屏幕上只显示一个菜单项,这是从列表中删除学生的项目。 必须为iOS特别标记从ListView中删除条目的菜单项。 Android屏幕列出了屏幕顶部的前两个菜单项。 只有Windows运行时才会列出它们。
要查看其他菜单项,请点击iOS上的“更多”按钮和Android上的垂直省略号。 其他项目显示在iOS屏幕底部的列表中以及Android屏幕右上角的下拉列表中:
201811041451210427
点击其中一个菜单项执行该操作。
要为单元格创建上下文菜单,可以将MenuItem类型的对象添加到Cell类定义的ContextActions集合中。 你已经遇到过MenuItem。 它是第13章“位图”中描述的ToolbarItem类的基类。
MenuItem定义了五个属性:

  • 字符串类型的文本
  • FileImageSource类型的图标,用于从平台项目访问位图
  • IsDestructive类型为bool
  • 类型为ICommand的命令
  • 类型为object的CommandParameter

此外,MenuItem定义了Clicked事件。 您可以在Clicked处理程序中处理菜单操作,或者如果菜单操作是在ViewModel-ICommand对象中实现的话。
以下是在CellContextMenu程序中初始化ContextActions集合的方法:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:school="clr-namespace:SchoolOfFineArt;assembly=SchoolOfFineArt"
             x:Class="CellContextMenu.CellContextMenuPage">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness"
                    iOS="0, 20, 0, 0" />
    </ContentPage.Padding>
    <ContentPage.BindingContext>
        <school:SchoolViewModel />
    </ContentPage.BindingContext>
    <StackLayout BindingContext="{Binding StudentBody}">
        <Label Text="{Binding School}"
               FontSize="Large"
               FontAttributes="Bold"
               HorizontalTextAlignment="Center" />
        <ListView ItemsSource="{Binding Students}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ImageCell ImageSource="{Binding PhotoFilename}"
                               Text="{Binding FullName}"
                               Detail="{Binding GradePointAverage,
                               StringFormat='G.P.A. = {0:F2}'}">
                        <ImageCell.ContextActions>
                            <MenuItem Text="Reset GPA"
                                      Command="{Binding ResetGpaCommand}" />
 
                            <MenuItem Text="Move to top"
                                      Command="{Binding MoveToTopCommand}" />
                            <MenuItem Text="Move to bottom"
                                      Command="{Binding MoveToBottomCommand}" />
                            <MenuItem Text="Remove"
                                      IsDestructive="True"
                                      Command="{Binding RemoveCommand}" />
                        </ImageCell.ContextActions>
                    </ImageCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

请注意,“删除”项的IsDestructive属性设置为True。 这是导致项目在iOS屏幕上以红色显示的属性,按照惯例,该属性会从集合中删除该项目。
MenuItem定义了一个Icon属性,您可以将其设置为存储在平台项目中的位图(非常类似于ToolbarItem使用的图标),但它仅适用于Android,并且位图替换了Text描述。
所有四个MenuItem对象的Command属性都绑定到Student类中的属性。
Student对象是单元格的绑定上下文,因此它也是这些MenuItem对象的绑定上下文。 以下是在Student中定义和初始化属性的方法:

public class Student : ViewModelBase
{
    __
    public Student()
    {
        ResetGpaCommand = new Command(() => GradePointAverage = 2.5);
        MoveToTopCommand = new Command(() => StudentBody.MoveStudentToTop(this));
        MoveToBottomCommand = new Command(() => StudentBody.MoveStudentToBottom(this));
        RemoveCommand = new Command(() => StudentBody.RemoveStudent(this));
    }
    __
    // Properties for implementing commands.
    [XmlIgnore]
    public ICommand ResetGpaCommand { private set; get; }
    [XmlIgnore]
    public ICommand MoveToTopCommand { private set; get; }
    [XmlIgnore]
    public ICommand MoveToBottomCommand { private set; get; }
    [XmlIgnore]
    public ICommand RemoveCommand { private set; get; }
    [XmlIgnore]
    public StudentBody StudentBody { set; get; }
}

只有ResetGpaCommand可以在Student类中完全处理。 其他三个命令需要访问StudentBody类中的学生集合。 因此,当首次加载数据时,SchoolViewModel将每个Student对象中的StudentBody属性设置为带有学生集合的StudentBody对象。 这允许通过调用StudentBody中的以下方法来实现Move和Remove命令:

public class StudentBody : ViewModelBase
{
    __
    public void MoveStudentToTop(Student student)
    {
        Students.Move(Students.IndexOf(student), 0);
    }
    public void MoveStudentToBottom(Student student)
    {
        Students.Move(Students.IndexOf(student), Students.Count - 1);
    }
    public void RemoveStudent(Student student)
    {
        Students.Remove(student);
    }
}

由于Students集合是ObservableCollection,因此ListView重绘自身以反映学生的新数字或新顺序。

目录
相关文章
|
vr&ar 图形学
【Unity3D 灵巧小知识点】 ☀️ | 快速查找场景中勾选Raycast Target的游戏对象
【Unity3D 灵巧小知识点】 ☀️ | 字符串截取,截取某个路径字符串中 末尾文件 的名字 47/100 发布文章 zhangay1998 未选择任何文件 Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。
【Unity3D 灵巧小知识点】 ☀️ | 快速查找场景中勾选Raycast Target的游戏对象
|
XML JavaScript Android开发