简体   繁体   English

删除项目后如何更新ListView?

[英]How to update a ListView after deleting an item?

In my application I drag and drop an item from the ListView in the trash button and it removes the item. 在我的应用程序中,我将一个项目从ListView拖放到垃圾箱按钮中,然后将其删除。 To see the change I have to go back a page and then open again the next page to see that the item was deleted. 要查看更改,我必须返回上一页,然后再次打开下一页以查看该项目已被删除。 What I want is when I drop the item to the trash button to show the update the same time. 我想要的是将项目放到垃圾箱按钮中以同时显示更新。

With the code I have right now, when I go to the page the ListView loads for a second and then it disappears. 使用我现在拥有的代码,当我转到页面时, ListView会加载一秒钟,然后消失。

Can anyone tell me how to solve this? 谁能告诉我如何解决这个问题? Here is my code: 这是我的代码:

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();   
        }
    }
}

Here is the binding I do in the XAML file: 这是我在XAML文件中执行的绑定:

 <ListView x:Name="CollectedItemsListView"
                  ItemsSource="{Binding refreshedItems}"
...

The problem is the viewModel is deleting directly from the Model, not itself 问题是viewModel是直接从Model中删除,而不是本身

i would suggest the following changes 我会建议以下更改

firstly you need to delete or refresh one of your ObservableCollections as part of the delete process (refreshedItems), this will then immediately notify anything bound to it that a change has occurred 首先,作为删除过程的一部分,您需要删除或刷新一个ObservableCollections(refreshedItems),然后它将立即通知与其绑定的任何对象已发生更改。

so remove CollectedItemsListView.ItemsSource = refreshedItems; 所以删除CollectedItemsListView.ItemsSource = refreshedItems; and update the collection instead 并更新集合

refreshedItems.Remove(deletedItem);

second remove all setters from the ObservableCollection properties, you need to update the content of the collections not replace the collections 第二次从ObservableCollection属性中删除所有设置器,您需要更新集合的内容而不是替换集合

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();   
        }
    }
}

EDIT: As your having trouble with the suggested changes here is a complete working example 编辑:由于您在此处无法进行建议的更改,因此是一个完整的工作示例

XAML 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>

Code Behind 背后的代码

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);
        }
    }
}

ViewModel 视图模型

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);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM