我创建了一个简单的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
对象时,SelectedItem
的ListView
为null,因此无法正确触发该事件。因此,将
ItemSource
的ListView(_wrappedItems)
更改为列表将解决此问题。