在列表视图项目上点击手势 [英] Tap Gesture on List View Items

查看:58
本文介绍了在列表视图项目上点击手势的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在列表视图中点击某个项目后,我试图打开另一个视图. 我尝试添加TapGestureRegonizer甚至使用网格等添加ViewCell.这些似乎都不起作用.我在标签上添加了轻按手势,这似乎可行,但对列表视图项却无效.对于列表视图之类的东西来说,这似乎是一个简单的问题,但是似乎没有内置的功能.

I am trying to open another view after tapping on an item in the list view. I have tried adding a TapGestureRegonizer and even adding ViewCell with grids etc. None of these seem to work. I have added a tap gesture to a label and that seemed to work but the same does not work for list view items. This seems like a simple problem for something like list view, but there doesnt seem to be a built in functionality for this.

Xaml:

<ListView x:Name="dataList"
      ItemsSource="{Binding routeLabels}"
      HasUnevenRows="True"
      Grid.Row="1"
      Grid.Column="0"
      Grid.ColumnSpan="3">
</ListView>

背后的代码:

var listviewgesture = new TapGestureRecognizer();
listviewgesture.SetBinding(TapGestureRecognizer.CommandProperty,"LoadRoutePage");
dataList.GestureRecognizers.Add(listviewgesture);

视图模型:

public ICommand LoadRoutePage { get; protected set; }



public DriverDashboardViewModel(INavigation navigation,MessagDatabase database)
    {
        this._database = database;
        this.Navigation = navigation;
        this.LoadNotifications = new Command(async () => await OpenNotificationsPage());
        this.LoadRoutePage = new Command(async () => await OpenRoutePage());

    }

public async Task OpenRoutePage()
    {

        await Navigation.PushAsync(new RoutePageView());
    }

请注意,LoadNotifications方法在打开页面时有效,但LoadRoutePage无效.因此,我知道视图和视图模型之间存在某种程度的通信.

Just to be clear the LoadNotifications method does work in opening a page but LoadRoutePage does not. So I know there is some level of communication between the view and viewmodel.

推荐答案

您不应在ListView上添加TapGestureRecognizer.每个单元格已经具有处理敲击事件,并且GestureRecognizer可能只会混淆ListView关于敲击应该做什么.有几种方法可以解决这个问题.

You should not be adding a TapGestureRecognizer to a ListView. Every cell already has events that handle tapping on them and a GestureRecognizer would probably only confuse the ListView regarding what the tap should be doing. There are a few ways to go about this.

1. SelectedItem绑定

SelectedItem属性绑定到ListView并在该属性的设置器中处理方法调用.

Bind a SelectedItem property to the ListView and handle your method calls in the setter of that property.

<ListView x:Name="dataList" ItemsSource="{Binding routeLabels}"
          HasUnevenRows="True" Grid.Row="1" Grid.Column="0"        
          Grid.ColumnSpan="3" SelectedItem="{Binding SelectedItem}">
</ListView>

在您的视图模型中:

string _selectedItem;

public string SelectedItem {
    get {return _selectedItem; } 
    set 
    { 
        _selectedItem = value;
        // Additional code
    }
}

2.使用内置事件ItemSelected或ItemTapped

一个ListView具有一些可以关联的事件,分别命名为ItemSelectedItemTapped.这些可以隐藏在代码的后面,并可以处理您要实现的目标.

A ListView has some events you can hook up named ItemSelected and ItemTapped. These can be caught in code-behind and can handle what you're trying to achieve.

<ListView x:Name="dataList" ItemsSource="{Binding routeLabels}"
          HasUnevenRows="True" Grid.Row="1" Grid.Column="0"        
          Grid.ColumnSpan="3" ItemSelected="Handle_ItemSelected" ItemTapped="Handle_ItemTapped">
</ListView>

3.使用事件来命令行为绑定

由于使用了视图模型,因此理想情况下不希望这些事件发生,因为它们是在UI端处理的.那里有NuGet软件包,可以将事件转换为可以在视图模型中处理的Command.例如,看看 Corcav.Behaviors .

Since you use viewmodels you ideally don't want these events since they're handled on the UI side. There are NuGet packages out there that can translate an event to a Command that you can handle in your viewmodel. Take a look at Corcav.Behaviors for example.

4.创建自己的行为

我有一个经常使用的人,像这样:

I have one I use regularly which looks like this:

public class ListViewSelectedItemBehavior : Behavior<ListView>
{
    public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(ListViewSelectedItemBehavior));

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public ListView AssociatedObject { get; private set; }

    protected override void OnAttachedTo(ListView bindable)
    {
        base.OnAttachedTo(bindable);
        AssociatedObject = bindable;
        bindable.BindingContextChanged += OnBindingContextChanged;
        bindable.ItemSelected += OnListViewItemSelected;
    }

    protected override void OnDetachingFrom(ListView bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.BindingContextChanged -= OnBindingContextChanged;
        bindable.ItemSelected -= OnListViewItemSelected;
        AssociatedObject = null;
    }

    private void OnBindingContextChanged(object sender, EventArgs e)
    {
        OnBindingContextChanged();
    }

    private void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        if (Command == null)
            return;

        if (Command.CanExecute(e.SelectedItem))
            Command.Execute(e.SelectedItem);
    }

    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();
        BindingContext = AssociatedObject.BindingContext;
    }
}

要将其添加到您的ListView中,只需向其添加行为:

To add this to your ListView you simply add a behavior to it:

<ListView x:Name="dataList" ItemsSource="{Binding routeLabels}"
          HasUnevenRows="True" Grid.Row="1" Grid.Column="0"        
          Grid.ColumnSpan="3">
    <ListView.Behaviors>
        <behaviors:ListViewSelectedItemBehavior Command="{Binding ItemSelectedCommand}" />
    </ListView.Behaviors>
</ListView>

在这种情况下,ItemSelectedCommand是ViewModel中的Command对象.

In this case ItemSelectedCommand is a Command object in your ViewModel.

这篇关于在列表视图项目上点击手势的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆