我创建了一个简单的MultiSelectListView,如下所示,但是不触发ItemSelected事件。

有人可以告诉我,是什么问题,因为我想我已经尝试了一切?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Xamarin.Forms;

namespace <myProject>.Views
{
   class MultiSelectListView<T> : ContentView
   {
      private ListView _lstView;
      private IEnumerable<WrappedSelection<T>> _wrappedItems;

      public IEnumerable<T> Items
      {
         get { return _wrappedItems?.Select(i => i.Item) ?? new T[0]; }
         set
         {
            _wrappedItems = value?.Select(item => new WrappedSelection<T> { Item = item });
            _lstView.ItemsSource = _wrappedItems;
         }
      }

      public MultiSelectListView(string bindingProperty, IEnumerable<T> items = null)
      {
         if (string.IsNullOrWhiteSpace(bindingProperty))
            throw new ArgumentNullException(nameof(bindingProperty));

         WrappedItemSelectionTemplate.BindingProperty = bindingProperty;

         Content = _lstView = new ListView(ListViewCachingStrategy.RecycleElement)
         {
            ItemTemplate = new DataTemplate(typeof(WrappedItemSelectionTemplate))
         };

         _lstView.ItemSelected += (sndr, e) =>
         {
            if (e.SelectedItem == null)
               return;

            var wrappedSelection = e.SelectedItem as WrappedSelection<T>;
            if (wrappedSelection != null)
               wrappedSelection.IsSelected = !wrappedSelection.IsSelected;

            var lstView = sndr as ListView;
            if (lstView != null)
               lstView.SelectedItem = null;
         };

         Items = items;
      }
   }

   class WrappedItemSelectionTemplate : ViewCell
   {
      public static string BindingProperty { get; internal set; }

      public WrappedItemSelectionTemplate()
      {
         var name = new Label { LineBreakMode = LineBreakMode.WordWrap, Style = Styles.GetTextStyle() };
         name.SetBinding(Label.TextProperty, new Binding($"Item{(!string.IsNullOrEmpty(BindingProperty) ? $".{BindingProperty}" : "")}"));

         var grid = new Grid
         {
            Children = { name },
            ColumnDefinitions = { new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) } }
         };

         View = grid;
      }
   }

   class WrappedSelection<T> : INotifyPropertyChanged
   {
      private bool _isSelected;

      public event PropertyChangedEventHandler PropertyChanged = delegate { };

      public bool IsSelected
      {
         get { return _isSelected; }
         set
         {
            if (_isSelected != value)
            {
               _isSelected = value;
               PropertyChanged(this, new PropertyChangedEventArgs(nameof(IsSelected)));
            }
         }
      }

      public T Item { get; set; }
   }
}

最佳答案

我创建了一个简单的MultiSelectListView,如下所示,但是不触发ItemSelected事件。


我已经测试了您的代码并转载了您的问题。我通过将_wrappedItems的类型转换为List<>类型来解决了该问题。

MultiSelectListView类内部,修改如下代码:

public IEnumerable<T> Items
{
      get { return _wrappedItems?.Select(i => i.Item) ?? new T[0]; }
      set
      {
         _wrappedItems = value?.Select(item => new WrappedSelection<T> { Item = item }).ToList();
         _lstView.ItemsSource = _wrappedItems;
      }
}


ListView.SelectedItem更改时,将触发ItemSelected事件。但是,当使用从IEnumerable返回的Linq对象时,SelectedItemListView为null,因此无法正确触发该事件。
因此,将ItemSourceListView(_wrappedItems)更改为列表将解决此问题。

10-04 13:50