0

Dans mon application, je fais glisser et déposer un élément du ListView dans le bouton de la corbeille et il supprime l'élément. Pour voir le changement je dois retourner à une page et puis ouvrir à nouveau la page suivante pour voir que l'article a été supprimé. Ce que je veux, c'est quand je dépose l'article au bouton de la corbeille pour montrer la mise à jour en même temps.Comment mettre à jour un ListView après avoir supprimé un élément?

Avec le code que j'ai en ce moment, quand je vais à la page ListView charge pendant une seconde, puis il disparaît.

Quelqu'un peut-il me dire comment résoudre ce problème? Voici mon 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(); 
     } 
    } 
} 

est ici I La liaison fais dans le fichier XAML:

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

il semble que vous définissez CollectedItemsListView.ItemsSource plusieurs fois, et la mise en page ne change pas, ce sur la liaison ItemsSource? – RTDev

+0

J'ai supprimé le CollectedItemsListVi ew.ItemsSource du TrashButton mais toujours le même, donc je l'appelle juste une fois. – Premo

+0

ne l'appelez pas, utilisez Binding dans le xaml, liez ItemsSource à ObservableCollection, puis chaque suppression, insertion et ainsi de suite (effectuée sur cette collection) sera correctement affichée sur la mise en page – RTDev

Répondre

3

Le problème est le viewmodel supprime directement à partir du modèle, ne se

i suggérerait les changements suivants

d'abord vous devez supprimer ou actualiser un de vos ObservableCollections dans le cadre du processus de suppression (refreshedItems), ce sera t poule aviser immédiatement quelque chose lié à ce qu'un changement a eu lieu

donc enlever CollectedItemsListView.ItemsSource = refreshedItems; et mettre à jour la collection à la place

refreshedItems.Remove(deletedItem); 

second degré tous les setters des propriétés ObservableCollection, vous devez mettre à jour le contenu des collections non remplacer les collections

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: Comme votre peine d'avoir avec les modifications proposées ici est un exemple de travail complet

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 Derrière

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

ok J'ai supprimé le CollectedItemsListView.ItemsSource = refreshedItems; Je vois que vous avez ajouté le refreshedItems.Remove (deletedItem); pourriez-vous expliquer à ce sujet et comment puis-je mettre à jour la collection? Je pensais mettre à jour la collection en appelant le itemsourse à nouveau. – Premo

+0

ObservableCollection implémente INotifyCollectionChanged ceci est utilisé par les bindings pour détecter les changements de la même manière qu'il utilise INotifyPropertyChanged pour détecter les changements de propriétés. Ainsi, chaque fois que vous ajoutez ou supprimez à la collection, la liaison la récupère automatiquement – MikeT

+0

ListView x: Name = "CollectedItemsListView" ItemsSource = "{Binding RefreshedItems}" 'XAML est sensible à la casse – MikeT