删除项目后如何更新ListView?

时间:2016-08-17 10:56:17

标签: c# listview uwp observablecollection inotifypropertychanged

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

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

谁能告诉我如何解决这个问题? 这是我的代码:

ListView

这是我在XAML文件中执行的绑定:

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

1 个答案:

答案 0 :(得分:3)

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

我会建议以下更改

首先,您需要删除或刷新一个ObservableCollections作为删除过程的一部分(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);
        }
    }
}