Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
637 views
in Technique[技术] by (71.8m points)

c# - MvvmCross - MvxListView binding multiple clicks

I am developing an app using MvvmCross and I am having problems in the android app setting up the binding to catch a click operation in two different controls that make up a MvxListView item. The binding for all the data within the ViewModel all works fine Here is the AXML for my FavouritesView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/LightGrey"
        android:scrollbars="vertical"
        android:scrollbarStyle="insideOverlay">
        <LinearLayout
                REMOVED FOR CLARITY    />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <Button
                style="@style/ButtonFont"
                android:text="Back"
                android:layout_width="80dp"
                android:layout_height="43dp"
                android:layout_marginTop="15dp"
                android:layout_marginLeft="12dp"
                android:background="@drawable/darkgrey_rounded_button"
                local:MvxBind="Text BackButtonText; Click CloseFragmentCommand"
                android:id="@+id/buttonBackFavourites"
                android:drawableLeft="@drawable/arrow_left"
                android:padding="8dp" />
            <TextView
                style="@style/TitleFont"
                android:text="Title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:layout_marginLeft="12dp"
                local:MvxBind="Text TitleText"
                android:id="@+id/textTitleFavouritess" />
            <Mvx.MvxListView
                local:MvxBind="ItemsSource Favourites; ItemClick ShowFavouriteCommand"
                local:MvxItemTemplate="@layout/item_favourite"
                android:divider="@color/LightGrey"
                android:dividerHeight="10dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:layout_marginTop="30dp"
                android:scrollbars="none"
                android:id="@+id/listFavourites" />
        </LinearLayout>
    </ScrollView>
</LinearLayout>

And the MvxItemTemplate is here:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/MidGrey">
    <TextView
        style="@style/GeneralFont"
        android:id="@+id/favItemText"
        android:text="Text line2 "
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="30dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:textColor="@color/DarkGrey"
        android:lines="2"
        local:MvxBind="Text Title" />
    <ImageView
        android:id="@+id/favItemImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="24dp"
        android:layout_marginRight="10dp"
        android:tint="@color/DarkGrey"
        android:src="@drawable/arrow_right" />
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:id="@+id/viewFavSpacer"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_below="@+id/favItemText"
        android:background="@color/DarkGrey" />
    <Button
        android:text="(x) Remove"
        android:layout_below="@+id/viewFavSpacer"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:textColor="@color/DarkGrey"
        android:textSize="12dp"
        android:background="@color/MidGrey"
        local:MvxBind="Text 'RemoveFromFavourites', Converter=UseTextService; Click DeleteFavouriteMessage(.)"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="10dp" />
</RelativeLayout>

Here is my FavouritesViewModel:

using System;
using Cirrious.MvvmCross.Plugins.Messenger;
using MyApp.Core.Managers;
using MyApp.Core.Services;
using System.Collections;
using MyApp.Core.Domain;
using System.Collections.Generic;
using Cirrious.MvvmCross.ViewModels;
using System.Collections.ObjectModel;
using System.ServiceModel.Channels;
using Cirrious.CrossCore;
using MyApp.Core.Messages;
using MyApp.Core.Helpers;

namespace MyApp.Core.ViewModels
{
    public class FavouritesViewModel: StandardsViewModel
    {
        private IFavouritesService _favouritesService;

        public FavouritesViewModel (ITextService textService, IMvxMessenger messenger, ISettingsManager settingsManager, IPageService pageService, IFavouritesService favouriteService): base(textService, messenger, settingsManager, pageService)
        {
            _logger.LeaveBreadcrumb ("FavouritesViewModel" , "Constructor");

            _favouritesService = favouriteService;
        }

        public string TitleText { get { return _textService.GetString("Favourites"); } }


        private ObservableCollection<Favourite> _favourites;
        public ObservableCollection<Favourite> Favourites
        {
            get { return _favourites; }
            set {
                _favourites = value;
                RaisePropertyChanged (()=>Favourites);
            }
        }

        public async new void Init()
        {
            _logger.LeaveBreadcrumb ("FavouritesViewModel" , "Init");

            var messenger = Mvx.Resolve<IMvxMessenger> ();
            messenger.Subscribe<DeleteFavouriteMessage>(message => {
                DeleteFavourite (message.ThisFavourite);
            });

            var favs = await _favouritesService.GetAll ();
            _logger.LeaveBreadcrumb ("FavouritesViewModel:Init", "Favourites found:" + favs.Count.ToString ());
            Favourites = new ObservableCollection<Favourite> (favs);
        }


        /// <summary>
        /// Deletes the favourite.
        /// </summary>
        /// <param name="favourite">Favourite.</param>
        public void DeleteFavourite(Favourite favourite)
        {
            _logger.LeaveBreadcrumb ("FavouritesViewModel:DeleteFavourite", favourite.Title);

            Favourites.Remove (favourite);
            RaisePropertyChanged ("Favourites");
            _favouritesService.Delete (favourite);
        }


        /// <summary>
        /// The delete favourite command.
        /// </summary>
        private MvxCommand<Favourite> _deleteFavouriteCommand;

        /// <summary>
        /// Gets the delete favourite command.
        /// </summary>
        /// <value>The delete favourite command.</value>
        public MvxCommand<Favourite> DeleteFavouriteCommand
        {
            get
            {
                _deleteFavouriteCommand = _deleteFavouriteCommand ?? new MvxCommand<Favourite> (DeleteFavourite);
                return _deleteFavouriteCommand;
            }
        }


        public void ShowFavourite(Favourite favourite)
        {
            if (favourite != null)
            {
                _logger.LeaveBreadcrumb (string.Format("FavouriteViewModel - Selected : {0}", favourite.Title));
                // TODO need to display the favourite piece of info
            }
        }

        private MvxCommand<Favourite> _showFavouriteCommand;
        public MvxCommand<Favourite> ShowFavouriteCommand
        {
        get
            {
                _showFavouriteCommand = _showFavouriteCommand ?? new MvxCommand<Favourite> (ShowFavourite);
                return _showFavouriteCommand;
            }
        }

        public string ButtonRemoveText { get { return _textService.GetString ("RemoveFromFavourites"); } }
        public string AreYouSureText { get { return _textService.GetString ("AreYouSure"); } }
        public string RemoveFavouriteText { get { return _textService.GetString ("RemoveFavourite"); } }
    }
}

The symptoms of my problem are the View receives the DeleteFavouriteMessage when the "(x) Remove" button is clicked. When the item is clicked the ItemClick event ShowFavouriteCommand does not get fired from the MvxListView.

I am sure I am doing something, or missing something simple, but I am struggling to make any progress.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I've encountered this before. The button in your MvxItemTemplate layout is stealing focus. Try setting android:focusable="false" for the button in your layout.

Changing focus from Button in ListView row to list item

I am updating this answer to be more thorough. While setting android:focusable="false"for a common Button control in a ListView Item fixes the issue. If you are using an ImageButton this will not work.

For an ImageButton you need to set android:descendantFocusability="blocksDescendants" on the root view of your layout.

See the accepted answer here: can't click on listview row with imagebutton


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...