Событие ItemDisappearing Listview Xamarin.Forms не вызывается, когда элемент удаляется из списка. - PullRequest
0 голосов
/ 31 мая 2018

Я новичок в Xamarin.Forms, у меня есть просмотр списка с источником элемента.

ItemSource ListView - это ObserverableCollection К сожалению, когда я удаляю элемент из ItemSourceсобытие ItemDisapperaing не сработало.Да, элемент списка удален из пользовательского интерфейса устройства Android.

Однако я реализовал ItemAppearing, и это прекрасно работает!Это сработало.

Добавление сценария работы предмета:

  1. Вызван ShopCart.Instance.AddItem(randomItem).
  2. ShopItemListView.ItemsSource обновляется с добавленным элементом.
  3. TotalAmount Текст обновляется с нужной суммой. Итак, вызывается функция ShopItem_NewItemAdded!

Очистка элементов из сценария Shopcart (не работает)

  1. ShopCart.Instance.Clear() вызывается.
  2. ShopItemListView.ItemShource будет пусто!Элементы, отсутствующие в интерфейсе пользователя!
  3. Но текст TotalAmount не изменился до 0.0!Он по-прежнему имеет предыдущее значение.

Похоже, что в элементе пользовательского интерфейса 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.Но кажется, что элемент пользовательского интерфейса не уведомлен.

Как я могу обновить TotalAmount метку на пользовательском интерфейсе после того, как я удалил все элементы магазина из корзины?

1 Ответ

0 голосов
/ 01 июня 2018

Возможно, вы ошиблись в использовании ItemDisappearing .Этот метод предназначен только для виртуализации.Не гарантируется запуск всех видимых элементов при удалении Списка с экрана.

Это означает, что если у вас есть список из 100 элементов, но вы можете видеть только 10 за раз из-за размера ячеек, когда вы прокручиваете вниз, и появляется новая ячейка, а верхняя ячейка прокручивается.за пределами экрана событие ItemDisappearing сработает.

Если вы просто хотите отобразить счетчик ItemsSource (в вашем случае ShopItems) в ListView на экране.Вы можете использовать Binding and Converter:

Сначала создайте конвертер:

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, метка будет показывать счет.

...