xamarin - 从列表中删除项目时不会触发 Xamarin.Forms Listview 的 ItemDisappearing 事件
问题描述
我是 Xamarin.Forms 的新手,我有一个带有项目源的列表视图。
ItemSource
ListView 的 是一个不幸的ObserverableCollection
,当我从 中删除一个项目时,不会触发ItemSource
该事件。ItemDisapperaing
是的,列表项已从 Android 设备的 UI 中删除。
但是我实现了ItemAppearing
并且效果很好!它触发了。
添加项目工作场景:
ShopCart.Instance.AddItem(randomItem)
被叫。ShopItemListView.ItemsSource
用新添加的项目刷新。TotalAmount
的文本以正确的数量更新。 所以调用了 ShopItem_NewItemAdded 函数!
从购物车场景中清除项目(不工作)
ShopCart.Instance.Clear()
叫。ShopItemListView.ItemShource
将是空的!不在 UI 上的项目!- 但是
TotalAmount
's 的文本没有更改为 0.0!它仍然具有以前的值。
似乎在 UI 元素上 TotalAmount 没有刷新!在调试中,我在清除后看到ShopItemListView.ItemsSource
列表为空。
所以ShopItem_ItemRemoved
函数没有被调用!
这里是 Xaml.cs
public ShopView()
{
InitializeComponent();
BindingContext = new ShopViewModel();
ShopItemListView.ItemsSource = Shop.Instance.ShopItems;
// This is triggered, it works
ShopItemListView.ItemAppearing += ShopItem_NewItemAdded;
// This event is not triggered, it does not work
ShopItemListView.ItemDisappearing += ShopItem_ItemRemoved;
}
// This event is not triggered, it does not work
private void ShopItem_ItemRemoved(object sender, ItemVisibilityEventArgs e)
{
// If I put a breakpoint here the debugger never comes into this method
TotalAmount.Text = Shop.Instance.ShopItems.Sum(si => si.Price).ToString();
if (Shop.Instance.ShopItems.Count == 0) {
ShopInformation.IsVisible = false;
}
}
// This is triggered, it works.
private void ShopItem_NewItemAdded(object sender, ItemVisibilityEventArgs e)
{
TotalAmount.Text = Shop.Instance.ShopItems.Sum(si => si.Price).ToString();
ShopInformation.IsVisible = true;
}
这是购物车单例实例
public sealed class ShopCart : INotifyPropertyChanged
{
private static readonly ShopCart _instance = new ShopCart();
private ShopCart()
{
ShopItems = new ObservableCollection<ShopCartItem>();
}
public static ShopCart Instance
{
get
{
return _instance;
}
}
public ObservableCollection<ShopCartItem> ShopItems { get; set; }
public void AddItem(ShopCartItem ShopCartItem)
{
ShopItems.Add(ShopCartItem);
OnPropertyChanged("ShopItems");
}
public void Clear()
{
ShopItems.Clear();
OnPropertyChanged("ShopItems");
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
ShopCart 实现了 INotifyPropertyChanged 接口。但似乎没有通知 UI 元素。
TotalAmount
从购物车中删除所有商品后,如何刷新 UI 上的标签?
解决方案
也许您误用了ItemDisappearing。此方法仅用于虚拟化。从屏幕上删除列表时,不能保证所有可见项目都会触发。
这意味着如果您有一个包含 100 个项目的列表,但由于单元格的大小,您一次只能看到 10 个,因为一旦您向下滚动并且一个新单元格进入视图,并且顶部单元格滚动离开屏幕,ItemDisappearing 事件会开火。
如果您只想ShopItems
在屏幕上显示 listView 的 ItemsSource(在您的情况下为 Count)计数。您可以使用绑定和转换器:
首先创建一个转换器:
public class ArrayToCountConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ObservableCollection<ShopCartItem> collection = value as ObservableCollection<ShopCartItem>;
return "There are" + collection.Count + "items";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后像这样使用它:
<ContentPage.Resources>
<ResourceDictionary>
<local:ArrayToCountConverter x:Key="ArrayToCountConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<Label Text="{Binding ShopItems, Converter={StaticResource ArrayToCountConverter}}"/>
您还需要设置BindingContext
:
public ShopCart shopCart = ShopCart.Instance;
public MainPage()
{
InitializeComponent();
this.BindingContext = shopCart;
MyListView.ItemsSource = shopCart.ShopItems;
}
这样当你ShopItems
在 ViewModel 中添加或清除时,标签会显示计数。
推荐阅读
- c# - 在 C# 中,有没有办法使 2 元素浮点数组等于 Unity Vector2 变量
- java - Java 文件复制 - 如何将输入文件备份/复制到其他目标位置?
- bixby - 实例化结构枚举
- php - 有没有办法更改我的主机名来修复“php_network_getaddresses:getaddrinfo failed: No such host is known.”?
- c# - UWP 从模板化 TabViewItem 获取子级
- flutter - 如何在颤动上禁用多视图,如 instagram
- z3 - z3 反例中的数组元素
- python - 如何从numpy中的指定数组获取欧几里德距离?
- css - 为什么我的 CSS 网格在 Chrome 中不起作用(适用于所有其他浏览器)
- reactjs - 通过输入检索信息时出错