[英]Xamarin.Forms ListView Deletion of Items holds old values
我有一个ListView并通过DataBinding将其填充到我的ViewModel中的Lists属性。 另外,我有一个ListView菜单,带有一个删除命令,也绑定到我的ViewModel。 我的问题是,如果我已经初始化ListView,我可以删除其中的列表。 如果我添加新列表,我可以删除所有列表。 但是,如果我添加新项目,我无法删除它们,因为我从DeleteCommand获取的列表是旧的,已经删除的列表。
因此,删除列表后,它们似乎在某种程度上,某处仍然存在,我只能删除新列表,如果当前列表的总量高于以前任何已删除列表的数量。
我希望这是对我的问题的某种可理解的解释。
Binding工作正常,我的ViewModel中的Lists Property保存正确的值,但DeleteListCommand中的“sender”ItemList是旧的ItemList。
这是我的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>
这是我的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));
}
根据示例项目,您需要执行以下操作:将单元命名为“viewCell”,因为您需要将单元格传递给模型才能重置ContextAction。 更改菜单项上的绑定以传递单元格而不是ItemList。 然后在模型重置上下文操作中,从单元格的绑定上下文中获取项目
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>
模型:
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.