如何在删除项后更新ListView

本文关键字:更新 ListView 删除 | 更新日期: 2023-09-27 18:02:47

在我的应用程序中,我从垃圾按钮的ListView中拖放一个项目,它删除了该项目。要查看更改,我必须返回一个页面,然后再次打开下一页,以查看该项目已被删除。我想要的是,当我把项目放到垃圾桶按钮时,可以同时显示更新。

使用我现在拥有的代码,当我进入页面时,ListView加载了一秒钟,然后它消失了。

谁能告诉我怎么解决这个问题?下面是我的代码:
public sealed partial class BasketPage : Page, INotifyPropertyChanged
{
    private MobileServiceCollection<Information, Information> tempItem;
    private ObservableCollection<Information> items;
    private ObservableCollection<Information> RefreshedItems { get; set; }
    private IMobileServiceTable<Information> informationTable = App.MobileService.GetTable<Information>();
    private Information selectedInformation;

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public BasketPage()
    {
        this.InitializeComponent();
        this.items = new ObservableCollection<Information>();
        this.refreshedItems = new ObservableCollection<Information>();
    }
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        getListData();
        base.OnNavigatedTo(e);
    }
    private async void getListData()
    {
        var query = App.conn.Table<Information>();
        foreach (var item in query)
        {
            tempItem = await informationTable
                .Where(todoItem => todoItem.Id == item.Name)
                .ToCollectionAsync();
            RefreshedItems.Add(tempItem.ElementAt(0));
        }           
    }
     private void BackButton_Click(object sender, RoutedEventArgs e)
    {
        if (Frame.CanGoBack)
        {
            Frame.GoBack();
        }
    }
    private void CollectedItemsListView_ItemClick(object sender, ItemClickEventArgs e)
    {
        selectedInformation = (Information)e.ClickedItem;
        Frame.Navigate(typeof(MediaViewPage), selectedInformation);
    }
    private void CollectedItemsListView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
    {
        var item = string.Join(",", e.Items.Cast<Information>().Select(i => i.Id));
        e.Data.SetText(item);
        e.Data.RequestedOperation = DataPackageOperation.Move;
    }
    private void TrashButton_DragOver(object sender, DragEventArgs e)
    {
        if (e.DataView.Contains(StandardDataFormats.Text))
        {
            e.AcceptedOperation = DataPackageOperation.Move;
        }
    }
    private async void TrashButton_Drop(object sender, DragEventArgs e)
    {
        if (e.DataView.Contains(StandardDataFormats.Text))
        {
            var id = await e.DataView.GetTextAsync();
            var query = App.conn.Table<Information>();
            var itemToDelete = query.Where(p => p.Name == id).FirstOrDefault();
            RefreshedItems.Remove(itemToDelete);
            App.conn.Delete(itemToDelete);
            App.conn.Commit();   
        }
    }
}
下面是我在XAML文件中做的绑定:
 <ListView x:Name="CollectedItemsListView"
                  ItemsSource="{Binding refreshedItems}"
...

如何在删除项后更新ListView

问题是viewModel直接从Model中删除,而不是本身

我建议做以下修改

首先,你需要删除或刷新一个observablecollection作为删除过程的一部分(refreshedItems),这将立即通知任何绑定到它的东西发生了变化

因此删除CollectedItemsListView.ItemsSource = refreshedItems;并更新集合

refreshedItems.Remove(deletedItem);

第二,从ObservableCollection属性中移除所有的setter,你需要更新集合的内容而不是替换集合

public sealed partial class BasketPage : Page, INotifyPropertyChanged
{
    private MobileServiceCollection<Information, Information> tempItem;
    private ObservableCollection<Information> Items{get;private set;}
    private ObservableCollection<Information> RefreshedItems{get;private set;}
    private IMobileServiceTable<Information> informationTable = App.MobileService.GetTable<Information>();
    private Information selectedInformation;

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public BasketPage()
    {
        this.InitializeComponent();
        this.Items = new ObservableCollection<Information>();
        this.RefreshedItems = new ObservableCollection<Information>();
    }
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        getListData();
        base.OnNavigatedTo(e);
    }
    private async void getListData()
    {
        var query = App.conn.Table<Information>();
        foreach (var item in query)
        {
            tempItem = await informationTable
                .Where(todoItem => todoItem.Id == item.Name)
                .ToCollectionAsync();
            RefreshedItems.Add(tempItem.ElementAt(0));
        }
    }
    private void BackButton_Click(object sender, RoutedEventArgs e)
    {
        if (Frame.CanGoBack)
        {
            Frame.GoBack();
        }
    }
    private void CollectedItemsListView_ItemClick(object sender, ItemClickEventArgs e)
    {
        selectedInformation = (Information)e.ClickedItem;
        Frame.Navigate(typeof(MediaViewPage), selectedInformation);
    }
    private void CollectedItemsListView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
    {
        var item = string.Join(",", e.Items.Cast<Information>().Select(i => i.Id));
        e.Data.SetText(item);
        e.Data.RequestedOperation = DataPackageOperation.Move;
    }
    private void TrashButton_DragOver(object sender, DragEventArgs e)
    {
        if (e.DataView.Contains(StandardDataFormats.Text))
        {
            e.AcceptedOperation = DataPackageOperation.Move;
        }
    }
    private async void TrashButton_Drop(object sender, DragEventArgs e)
    {
        if (e.DataView.Contains(StandardDataFormats.Text))
        {
            var id = await e.DataView.GetTextAsync();
            var query = App.conn.Table<Information>();
            var itemToDelete = query.Where(p => p.Name == id).FirstOrDefault();
            RefreshedItems.Remove(itemToDelete);
            App.conn.Delete(itemToDelete);
            App.conn.Commit();   
        }
    }
}

编辑:由于您对建议的更改有问题,这里是一个完整的工作示例

XAML

<Window x:Class="CollectionBindingDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CollectionBindingDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:CollectionList x:Name="CollectionList"/>
    </Window.DataContext>
    <StackPanel>
        <Button Click="Add_Click">add</Button>
        <Button Click="Remove_Click">remove</Button>
        <ListView x:Name="ListVeiw" ItemsSource="{Binding IntegerNumbers}"/>
    </StackPanel>
</Window>

背后的代码
namespace CollectionBindingDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void Add_Click(object sender, RoutedEventArgs e)
        {
            CollectionList.Add();
        }
        private void Remove_Click(object sender, RoutedEventArgs e)
        {
            var i = ListVeiw.SelectedItem as int?;
            if(i.HasValue)
                CollectionList.Remove(i.Value);
        }
    }
}

视图模型

namespace CollectionBindingDemo
{
    public class CollectionList
    {
        private Random rnd = new Random();
        public ObservableCollection<int> IntegerNumbers { get; } = new ObservableCollection<int>();

        public void Add()
        {
            IntegerNumbers.Add(rnd.Next(1000));
        }
        public void Remove(int i)
        {
            IntegerNumbers.Remove(i);
        }
    }
}