【问题标题】:MultiSelectable ListView - ItemSelected is not calledMultiSelectable ListView - ItemSelected 未被调用
【发布时间】:2017-08-11 23:36:41
【问题描述】:

我创建了一个简单的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; }
   }
}

【问题讨论】:

  • 你能分享你的 xaml 吗?
  • 我没有任何 XAML?

标签: c# android xamarin uwp xamarin.forms


【解决方案1】:

我已经创建了一个简单的 MultiSelectListView,如下所示,但不知何故 ItemSelected 事件没有被触发。

我已经测试了您的代码并重现了您的问题。我通过将_wrappedItems 的类型转换为List&lt;&gt; 类型解决了这个问题。

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事件将被触发。但是当使用从Linq返回的IEnumerable对象时,ListViewSelectedItem为空,因此无法正确触发事件。 所以把ListView(_wrappedItems)ItemSource改成列表就可以解决问题了。

【讨论】:

    猜你喜欢
    • 2017-01-11
    • 2017-02-04
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    相关资源
    最近更新 更多