【问题标题】:TapGesture on Image within ViewCell doesn't update SelectedItemViewCell 中图像上的 TapGesture 不会更新 SelectedItem
【发布时间】:2016-11-02 06:35:59
【问题描述】:

我创建了一个 ListView,其中每个单元格都有自己的图像。 单击图像时,会触发我的命令,并到达 ViewModel 中的方法“OpenImageAsync”,但未更新 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));
            }
        }
    }

【问题讨论】:

  • 你可能应该利用那里的CommandParameter ;)
  • 如 CommandParameter="{Binding SelectedPollStatistic}" ?
  • 我不确定,但你试过Mode=TwoWay吗?
  • 是的,如果你绑定一些值来标识你可以用来进一步导航的对象,那么就是这样!它将作为参数提供给您的Command 方法
  • @EgorGromadskiy - TapGesture 没有 Mode 属性。

标签: listview command xamarin.forms selecteditem


【解决方案1】:

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

我不知道CommandParameter 知道所选项目的实体——即使尚未引发 ItemTapped 事件。 所以我不得不像 Gerald 提到的那样使用CommandParameter

ViewModel 中的命令

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

Xaml

<Image.GestureRecognizers>
   <TapGestureRecognizer
      Command="{Binding Path=BindingContext.OpenImageCommand, Source={x:Reference EndPageContentPage}}"
      CommandParameter="{Binding Id}" />
</Image.GestureRecognizers>

【讨论】:

    【解决方案2】:

    我使用的行为:

    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 将被点击项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多