ViewCell中的图像TapGesture不会更新SelectedItem

时间:2016-06-30 09:02:25

标签: listview command xamarin.forms selecteditem

我创建了一个ListView,其中每个单元格都有自己的图像。 单击图像时,我的命令被触发,方法" OpenImageAsync"到达ViewModel但未更新SelectedItem。它始终为NULL 。 我试图按照本指南但没有运气。 http://rasmustc.com/blog/Image-Gallery-With-Xamarin-Forms/

的Xaml

<ListView
        x:Name="ListViewName"
        ItemsSource="{Binding PollStatistics}"
        SelectedItem="{Binding SelectedPollStatistic}">
        <ListView.ItemTemplate>
          <DataTemplate>
            <ViewCell>
              <StackLayout>
                    <Image
                      Source="{Binding Image, Converter={StaticResource ByteArrayToImage}}">
                      <Image.GestureRecognizers>
                        <TapGestureRecognizer
                            Command="{Binding Path=BindingContext.OpenImageCommand, Source={x:Reference EndPageContentPage}}"
                            CommandParameter="Image" />
                      </Image.GestureRecognizers>
                    </Image>
              </StackLayout>
            </ViewCell>
          </DataTemplate>
        </ListView.ItemTemplate>
      </ListView>

Xaml.cs

public partial class EndPage : BaseContentPage
    {
        public EndPage(INavigation navigation, User user)
        {
            InitializeComponent();
            this.BindingContext = new EndPageViewModel(navigation, user);
        }
    }

视图模型

public class EndPageViewModel : BaseViewModel, IIsLoadSpinnerRunning
    {
        private readonly INavigation _navigation;
        private readonly User _user;
        private readonly PollStatisticManager _pollStatisticManager = PollStatisticManager.DefaultManager;
        private ObservableCollection<PollStatisticDTO> _pollStatistics;
        private PollStatisticDTO _selectedPollStatistic;
        public EndPageViewModel(INavigation navigation, User user)
        {
            this._navigation = navigation;
            this._user = user;
            OpenImageCommand = new Command(async () => await OpenImageAsync());
            PollStatistics = await _pollStatisticManager.GetPollStatisticsForSessionAsync(sessionData);
        }
        public ObservableCollection<PollStatisticDTO> PollStatistics
        {
            get
            {
                return _pollStatistics;
            }
            set
            {
                _pollStatistics = value;
                OnPropertyChanged("PollStatistics");
            }
        }
        public PollStatisticDTO SelectedPollStatistic
        {
            get
            {
                return _selectedPollStatistic;
            }
            set
            {
                _selectedPollStatistic = value;
                OnPropertyChanged("SelectedPollStatistic");
            }
        }
        public ICommand OpenImageCommand { get; set; }
        private async Task OpenImageAsync()
        {
            if (SelectedPollStatistic != null)
            {
                await _navigation.PushModalAsync(new ImageModalPage(_navigation, SelectedPollStatistic.Image));
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

我使用了行为:

namespace XamarinApp.Behaviors
{
public class ListViewItemTappedBehavior : Behavior<ListView>
{
    #region Bindable properties
    public static readonly BindableProperty CommandProperty =
        BindableProperty.Create(nameof(Command),
                                typeof(ICommand),
                                typeof(ListViewItemTappedBehavior),
                                default(ICommand));

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

    protected override void OnAttachedTo(ListView listView)
    {
        base.OnAttachedTo(listView);

        listView.ItemTapped += OnItemTapped;
    }

    protected override void OnDetachingFrom(ListView listView)
    {
        base.OnDetachingFrom(listView);

        listView.ItemTapped -= OnItemTapped;
    }

    private void OnItemTapped(object sender, ItemTappedEventArgs e)
    {
        var listView = sender as ListView;
        listView.SelectedItem = null;

        if (Command != null && Command.CanExecute(e.Item))
        {
            Command.Execute(e.Item);
        }
    }
}
}


<ContentPage x:Name="Page"
             xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:behaviors="clr-namespace:XamarinApp.Behaviors;assembly=XamarinApp">

      <ListView ItemsSource="{Binding Items}">
        <ListView.Behaviors>
          <behaviors:ListViewItemTappedBehavior Command="{Binding BindingContext.NavigateToDetailsPageCommand, Source={x:Reference Page}}"/>
        </ListView.Behaviors>
        <ListView.ItemTemplate>
          <DataTemplate>
            <ViewCell>
              ...
            </ViewCell>
          </DataTemplate>
        </ListView.ItemTemplate>
      </ListView>
</ContentPage>

CommandParameter将被点击。

答案 1 :(得分:0)

感谢@EgorGromadskiy和@GeraldVersluis - 即使我没有使用你的代码Egor,你们都帮我弄清楚如何解决这个问题。

我不知道的是fetchRequest.entity = entityDescription fetchRequest.propertiesToFetch = ["info1", "info2"] fetchRequest.includesSubentities = true 知道所选项目的实体 - 即使ItemTapped事件没有被提出。 所以我必须使用Gerald提到的CommandParameter

ViewModel中的命令

CommandParameter

<强>的Xaml

public ICommand OpenImageCommand
    {
        get
        {
            return _openImageCommande ?? new Command<Guid>(async (itemId) =>
            {
                SelectedPollStatistic = PollStatistics.Single(x => x.Id == itemId);
                await OpenImageAsync();
            });
        }
    }