【问题标题】:Xamarin.Forms ListView Deletion of Items holds old valuesXamarin.Forms ListView 删除项目保存旧值
【发布时间】:2018-02-07 01:36:29
【问题描述】:

我有一个 ListView 并通过 DataBinding 将它填充到我的 ViewModel 中的 Lists 属性。此外,我有一个 ListView 菜单,带有一个删除命令,也绑定到我的 ViewModel。 我现在的问题是,如果我初始化了 ListView,我可以删除其中的列表。如果我添加新列表,我可以删除所有列表。但是,如果我添加新项目,我无法删除它们,因为我从 DeleteCommand 获得的列表是旧的、已删除的列表。

因此,在删除列表后,它们似乎以某种方式仍然存在,如果当前列表的总数高于以前删除的列表的数量,我只能删除新列表。

我希望这是对我的问题的某种可以理解的解释。

绑定正在工作,并且我的 ViewModel 中的 Lists 属性具有正确的值,但 DeleteListCommand 中的“发送者”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));
        }

【问题讨论】:

  • 什么是“项目列表”?它也可以观察到吗?
  • 它只是一个普通类,用作我的数据库的模型,用于带有字符串和布尔属性的 sqlite-net-pcl。我还将这个类用于 ObservableCollection,这样我就不必强制转换为不同的类型。我应该如何使它可观察?
  • 所以,这不是一个列表吗?我知道您正在使用嵌套列表。对吗?
  • 我想这会回答你的问题。不幸的是,我无法将其发布为答案,因为我无法将其归功于 forums.xamarin.com/discussion/86578/…
  • 该错误已在 bugzilla 上报告,ID 为 42516:bugzilla.xamarin.com/show_bug.cgi?id=42516

标签: c# xaml listview data-binding xamarin.forms


【解决方案1】:

基于示例项目,您需要执行以下操作:将单元命名为“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));
        }
    }
}

【讨论】:

    猜你喜欢
    • 2016-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-15
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多