与ObservableCollection一起使用的Listview在从同一页面删除时不会正确加载最后一项

问题描述 投票:0回答:2

我想在listview中显示学生列表。我已经使用ObservableCollection作为我的listview的ItemSource,当我尝试添加到Collection时,它成功地在UI中显示。当我尝试从集合中删除项目时出现问题我已在下面附加了图像。集合长度减1,这是正确的,但该元素根本不显示。 (如果我在删除之前在我的集合中有n元素,那么也会发现同样的行为,即只有最后一个元素没有正确显示,并且所有第一个n-1元素都按预期显示)

xamarin forum link for question

请访问上面的链接,了解问题的详细视觉描述。

提前致谢。

listview xamarin.forms observablecollection xamarin.forms.listview
2个回答
0
投票

根据你的描述,你没有放一些关于如何从Observablecollection中删除项目的代码,我猜你在删除项目时可能会遇到一些问题,我从ListView做一个关于删除项目的示例,你可以看看:

 <ListView
            IsPullToRefreshEnabled="true"
            ItemSelected="OnSelection"
            ItemTapped="OnTap"
            ItemsSource="{Binding}"
            Refreshing="OnRefresh">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ViewCell.ContextActions>
                            <!--
                                CommandParameter is the command to pass to the clicked event handler. Because these are menu items,
                                not cells managed by the ListView, CommandParameter is neccesary to determine which
                                cell the context action was taken on.
                            -->
                            <MenuItem
                                Clicked="OnMore"
                                CommandParameter="{Binding Name}"
                                Text="More" />
                            <MenuItem
                                Clicked="OnDelete"
                                CommandParameter="{Binding Name}"
                                IsDestructive="true"
                                Text="Delete" />
                        </ViewCell.ContextActions>
                        <StackLayout Padding="15,0">
                            <Label Text="{Binding Name}" />
                            <Label Text="{Binding Age}" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>



[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Page2 : ContentPage
{
    public static ObservableCollection<student> items { get; set; }
    public Page2 ()
    {
        InitializeComponent ();
        items = new ObservableCollection<student>()
        {
            new student(){Name="Cherry",Age=12},
        new student() { Name = "Nock", Age = 13 },
        new student() { Name = "Mattew", Age = 13 }


        };
        this.BindingContext = items;
    }

    private void OnSelection(object sender, SelectedItemChangedEventArgs e)
    {

        if (e.SelectedItem == null)
        {
            return;
        }
        DisplayAlert("Item Selected", ((student)e.SelectedItem).Name.ToString(), "Ok");
    }

    private void OnTap(object sender, ItemTappedEventArgs e)
    {
        DisplayAlert("Item Tapped", ((student)e.Item).Name.ToString(), "Ok");
    }

    private void OnRefresh(object sender, EventArgs e)
    {
        var list = (ListView)sender;
        //put your refreshing logic here
        var itemList = items.Reverse().ToList();
        items.Clear();
        foreach (var s in itemList)
        {
            items.Add(s);
        }
        //make sure to end the refresh state
        list.IsRefreshing = false;
    }

    private void OnMore(object sender, EventArgs e)
    {
        var item = (MenuItem)sender;

        DisplayAlert("More Context Action", item.CommandParameter.ToString() + " more context action", "OK");
    }

    private void OnDelete(object sender, EventArgs e)
    {
        var item = (MenuItem)sender;
        student s = (from itm in items
                         where itm.Name == item.CommandParameter.ToString()
                         select itm)
              .FirstOrDefault<student>();
        items.Remove(s);

    }
}

public class student
{
    public string Name { get; set; }
    public Int32 Age { get; set; }
}

0
投票

@樱桃,

我在Android上解决了这个问题,但同样的解决方案在iOS中无效。

以前我在我的ViewModel中使用Object of ObservableCollection并使用方法将同一个实例返回到listView.Itemsource,如下所示,

在ViewModel中:

private static ObservableCollection<Student> listofStds = new ObservableCollection<Student>();

public static ObservableCollection<Student> GetStudents()
{return listofStds;}

在视图中:

listView.ItemsSource = StudentsViewModel.GetStudents();

现在我用上面的代码改了

在ViewModel中:

class StudentsViewModel : INotifyPropertyChanged

private static List<Student> listofStds { get; set; }
public ObservableCollection<Student> listofStd
{
   get
   {
       return new ObservableCollection<Student>(listofStds);
   }
   set
  {
       //listofStds = value;
       OnPropertyChanged("listofStd");
   }
}

在视图中:

StudentsViewModel viewModel = new StudentsViewModel();

BindingContext = viewModel;
listView.SetBinding(ListView.ItemsSourceProperty, "listofStd");

在iOS中,当我运行相同的代码时,给定的消息显示在调试窗口中。

2019-02-13 16:52:14.323411+0530 NewStudentApp.iOS[90746:419211] SecTaskLoadEntitlements failed error=22 cs_flags=200, pid=90746
2019-02-13 16:52:14.323666+0530 NewStudentApp.iOS[90746:419211] SecTaskCopyDebugDescription: NewStudentApp.iO[90746]/0#-1 LF=0
© www.soinside.com 2019 - 2024. All rights reserved.