简体   繁体   English

Xamarin.Forms ListView项目删除包含旧值

[英]Xamarin.Forms ListView Deletion of Items holds old values

I have a ListView and populate it via DataBinding to a Lists Property in my ViewModel. 我有一个ListView并通过DataBinding将其填充到我的ViewModel中的Lists属性。 Additionally, I have a menu for the ListView, with a Delete Command, also bound to my ViewModel. 另外,我有一个ListView菜单,带有一个删除命令,也绑定到我的ViewModel。 My Problem is now, if I have the ListView initialized, I can delete the lists in it. 我的问题是,如果我已经初始化ListView,我可以删除其中的列表。 If I add new lists, I can delete all lists. 如果我添加新列表,我可以删除所有列表。 But then, if I add new items, I can't delete them, because the List I get from the DeleteCommand is the old, already deleted list. 但是,如果我添加新项目,我无法删除它们,因为我从DeleteCommand获取的列表是旧的,已经删除的列表。

So, after deleting lists, they seem to be somehow, somewhere still present and I can only delete new lists, if the total amount of current lists is higher, than any previous amount of deleted lists. 因此,删除列表后,它们似乎在某种程度上,某处仍然存在,我只能删除新列表,如果当前列表的总量高于以前任何已删除列表的数量。

I hope this is a somehow understandable explanation of my problem. 我希望这是对我的问题的某种可理解的解释。

The Binding is working and Lists Property in my ViewModel holds the correct values, but the "sender" ItemList in the DeleteListCommand is the old ItemList. Binding工作正常,我的ViewModel中的Lists Property保存正确的值,但DeleteListCommand中的“sender”ItemList是旧的ItemList。

Here is my XAML for my ListView: 这是我的ListView的XAML:

<ListView x:Name="listView" ItemsSource="{Binding Lists}" >
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell x:Name="viewCell">
                <ViewCell.ContextActions>
                    <MenuItem Command="{Binding BindingContext.RenameListCommand, Source={x:Reference listView}}" CommandParameter="{Binding .}" Text="Rename" />
                    <MenuItem Command="{Binding BindingContext.DeleteListCommand, Source={x:Reference listView}}" CommandParameter="{Binding .}" IsDestructive="True" Text="Delete" />
                </ViewCell.ContextActions>
                <ContentView Margin="0,2,0,2"
                                    HeightRequest="50"
                                    BackgroundColor="{Binding Color}">

                    <ContentView.GestureRecognizers>
                        <TapGestureRecognizer BindingContext="{Binding Source={x:Reference listView}, Path=BindingContext}"
                                                        Command="{Binding ListTappedCommand}" 
                                                        CommandParameter="{Binding Source={x:Reference viewCell}, Path=BindingContext}" />
                    </ContentView.GestureRecognizers>
                    <ContentView.Content>

                        <Label Text="{Binding Name}"
                                    HorizontalTextAlignment="Center"
                                    VerticalTextAlignment="Center"
                                    TextColor="White" 
                                    IsEnabled="True"/>
                    </ContentView.Content>

                </ContentView>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

And here is my ViewModel: 这是我的ViewModel:

...
public ObservableCollection<ItemList> lists = new ObservableCollection<ItemList>();
        public ObservableCollection<ItemList> Lists
        {
            get { return lists; }
            set
            {
                lists = value;
                OnPropertyChanged("Lists");
            }
        }
public event PropertyChangedEventHandler PropertyChanged;

...

this.DeleteListCommand = new Command<ItemList>((sender) =>
            {
                    OnDeleteList(sender);
            });

...

public ICommand DeleteListCommand { get; set; }
private void OnDeleteList(ItemList itemList)
        {
            Lists.Remove(itemList);
        }

...

protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

Based on sample project here is what you need to do: Name you cell "viewCell" because you need to pass cell to your model to be able to reset ContextAction. 根据示例项目,您需要执行以下操作:将单元命名为“viewCell”,因为您需要将单元格传递给模型才能重置ContextAction。 Change binding on menu item to pass the cell instead of ItemList. 更改菜单项上的绑定以传递单元格而不是ItemList。 Then in model reset context action and get an item from binding context of the cell 然后在模型重置上下文操作中,从单元格的绑定上下文中获取项目

XAML: XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:TobyList_XamarinForms"
                 xmlns:localVM="clr-namespace:TobyList_XamarinForms.ViewModels"
                 Title="Toby" 
             x:Class="TobyList_XamarinForms.Views.MasterPage">

    <StackLayout Padding="5" VerticalOptions="FillAndExpand" BackgroundColor="#F9F9F9">

        <StackLayout.BindingContext>
            <localVM:MasterPageViewModel />
        </StackLayout.BindingContext>


        <ListView x:Name="listView" ItemsSource="{Binding Lists}" CachingStrategy="RecycleElement">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell x:Name="viewCell">
                    <ViewCell.ContextActions>
                            <MenuItem Command="{Binding Path=BindingContext.DeleteListCommand, Source={x:Reference Name=listView}}" CommandParameter="{Binding Source={x:Reference viewCell}}" Text="Delete" />
                        </ViewCell.ContextActions>
                    <ContentView Margin="0,2,0,2"
                                        HeightRequest="50"
                                        BackgroundColor="{Binding Color}">

                        <ContentView.GestureRecognizers>
                            <TapGestureRecognizer BindingContext="{Binding Source={x:Reference listView}, Path=BindingContext}"
                                                            Command="{Binding ListTappedCommand}" 
                                                            CommandParameter="{Binding Source={x:Reference viewCell}, Path=BindingContext}" />
                        </ContentView.GestureRecognizers>
                        <ContentView.Content>

                            <Label Text="{Binding Name}"
                                        HorizontalTextAlignment="Center"
                                        VerticalTextAlignment="Center"
                                        TextColor="White"/>
                        </ContentView.Content>

                    </ContentView>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

        <StackLayout Orientation="Horizontal" HeightRequest="30" Margin="7">
            <Label Text="Add">
                <Label.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding AddListCommand}" />
                </Label.GestureRecognizers>
            </Label>

        </StackLayout>

    </StackLayout>

</ContentPage>

Model: 模型:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using TobyList_XamarinForms.Models;
using Xamarin.Forms;
using System.Linq;

namespace TobyList_XamarinForms.ViewModels
{
    public class MasterPageViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<ItemList> lists = new ObservableCollection<ItemList>();
        public ObservableCollection<ItemList> Lists
        {
            get { return lists; }
            set
            {
                lists = value;
                OnPropertyChanged("Lists");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public MasterPageViewModel()
        {
            this.AddListCommand = new Command(() =>
            {
                OnAddList();
            });
            //this.DeleteListCommand = new Command<ItemList>((sender) =>
            //{
            //  OnDeleteList(sender);
            //});

            this.DeleteListCommand = new Command<ViewCell>((sender) =>
            {
                OnDeleteList(sender);
            });

        }

        public ICommand AddListCommand { get; protected set; }
        private void OnAddList()
        {
            ItemList itemList = new ItemList() { Id = Guid.NewGuid().ToString().ToUpper(), Name = "Lorem Ipsum", Color = "#000000" };
            Lists.Add(itemList);
        }

        public ICommand DeleteListCommand { get; set; }
        //public void OnDeleteList(ItemList itemList)
        //      {
        //          Lists.Remove(itemList);
        //      }
        public void OnDeleteList(ViewCell viewCell)
        {
            viewCell.ContextActions.Clear();
            Lists.Remove((ItemList)viewCell.BindingContext);
        }

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

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

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