Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

Xamarin.FormsのListViewでタップされた項目をスマートにViewModelに渡す方法

$
0
0

EventToCommandBehaviorを使います。コードはこちらを参考に。

github.com

この時、こういうBehaviorを作っておくとListViewの選択がされなくなって捗ります。

using Xamarin.Forms;

namespace PrismUnityApp2
{
    publicclass NotSelectableListViewBehavior : Behavior<ListView>
    {
        protectedoverridevoid OnAttachedTo(ListView bindable)
        {
            base.OnAttachedTo(bindable);

            bindable.ItemSelected += this.Bindable_ItemSelected;
        }

        protectedoverridevoid OnDetachingFrom(ListView bindable)
        {
            base.OnDetachingFrom(bindable);
            bindable.ItemSelected -= this.Bindable_ItemSelected;
        }

        privatevoid Bindable_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            ((ListView)sender).SelectedItem = null;
        }
    }
}

SelectedItemをItemSelectedでnullにしてるのですが、こうすることで選択時に色がつかなくなります。 色がついてると同じアイテムを2回選択したときにイベントが飛ばないので強制的に選択をしないようにしているという感じですね。

あとは、SelectedItemChangedEventArgsから選択項目を抜き出すConverterを作って

using System;
using System.Globalization;
using Xamarin.Forms;

namespace PrismUnityApp2
{
    publicclass SelectedItemChangedEventArgsToSelectedItemConverter : IValueConverter
    {
        publicobject Convert(objectvalue, Type targetType, object parameter, CultureInfo culture)
        {
            var args = (SelectedItemChangedEventArgs)value;
            return args.SelectedItem;
        }

        publicobject ConvertBack(objectvalue, Type targetType, object parameter, CultureInfo culture)
        {
            thrownew NotImplementedException();
        }
    }
}

こんな風にListViewに対して設定すればOKです。

<?xml version="1.0" encoding="utf-8"?><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"xmlns:local="clr-namespace:PrismUnityApp2"prism:ViewModelLocator.AutowireViewModel="True"x:Class="PrismUnityApp2.Views.MainPage"Title="MainPage"><ContentPage.Resources><ResourceDictionary><local:SelectedItemChangedEventArgsToSelectedItemConverter x:Key="SelectedItemChangedEventArgsToSelectedItemConverter" /></ResourceDictionary></ContentPage.Resources><Grid><ListView ItemsSource="{Binding People}"><ListView.Behaviors><local:NotSelectableListViewBehavior /><local:EventToCommandBehavior EventName="ItemSelected"Converter="{StaticResource SelectedItemChangedEventArgsToSelectedItemConverter}"Command="{Binding SelectedCommand}"/></ListView.Behaviors></ListView></Grid></ContentPage>

大事なのは、ViewModel側のCommandでnullは受け付けないようにするところです。これをやらないと無駄にコマンドが実行されます。 (初回表示のときや、ItemSelectedイベントでnullをセットしたときとかにイベントが発生するので)

using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace PrismUnityApp2.ViewModels
{
    publicclass MainPageViewModel : BindableBase, INavigationAware
    {
        public IEnumerable<Person> People { get; } = Enumerable.Range(1, 100)
            .Select(x => new Person { Name = $"tanaka {x}" })
            .ToArray();

        public DelegateCommand<Person> SelectedCommand { get; }

        public MainPageViewModel()
        {
            this.SelectedCommand = new DelegateCommand<Person>(
                x => Debug.WriteLine($"{x.Name} selected."), 
                x => x != null);
        }

        publicvoid OnNavigatedFrom(NavigationParameters parameters)
        {
        }

        publicvoid OnNavigatedTo(NavigationParameters parameters)
        {
        }
    }

    publicclass Person
    {
        publicstring Name { get; set; }
    }
}

以上、簡単にですが最近得たノウハウ。


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>