我创建了一个简单的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; }
}
}
答案 0 :(得分:2)
我创建了一个简单的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
的{{1}}为空,因此不会正确触发事件。
因此,将ListView
ItemSource
更改为列表可以解决问题。