【问题标题】:Removing an item from a grouped LLS without re-assigning itemsource?在不重新分配 itemssource 的情况下从分组的 LLS 中删除项目?
【发布时间】:2013-09-21 00:32:14
【问题描述】:

我目前在分组的 WP8 应用程序中实现了 LLS (LongListSelector)。我有一个来自 WPToolkit 的上下文菜单。我希望找到如何在不重新分配 LLS 的项目源的情况下从我的 LLS 中删除项目。删除项目后,我想保持在列表中的位置是有道理的。

我现在拥有的是一个保存所有对象的主列表,它被传递给“GetGroup”函数以返回一个 Observable 组集合作为项目源。我现在明白了,简单地从主列表中删除并不会从项目源中删除。因此,我从主列表中删除,并将 ItemSource 转换为 Observable 集合并从中删除。它一直有效,直到特定实例(删除列表中的倒数第二个项目)。然后我得到一个神秘的异常(值超出范围)。但是,通过调试,所有正确的值都被调用和删除,随后出现异常。我怎样才能以正确的方式做到这一点?我做错了什么?我的代码 sn-ps 如下。

分组:

    private ObservableCollection<Model.Cartitem> cartList = new ObservableCollection<Model.allItems>(); // Overall Item list for current instance.  

    class Group<T> : ObservableCollection<T>, INotifyPropertyChanged
    {
        public Group(string name, IEnumerable<T> items)
            : base(items)
        { 
            this.imagePath = new Uri(name, UriKind.Relative);
        }
        private String _Title;
        private Uri _imagePath;

        public string Title
        {
            get
            {
                return _Title;
            }

            set
            {
                if (_Title != value)
                {
                    _Title = value;
                    NotifyPropertyChanged("Title");
                }
            }
        }


        public Uri imagePath
        {
            get
            {
                return _imagePath;
            }

            set
            {
                if (_imagePath != value)
                {
                    _imagePath = value;
                    NotifyPropertyChanged("imagePath");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,
                    new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    // Functions to Handle Group Lists
    private ObservableCollection<ITemClass> GetItemList()
    {
        return allItems;
    }

    private ObservableCollection<Group<ItemClass>> GetItemGroups()
    {
        IEnumerable<ItemClass> tempItemList = GetCartList();
        return GetItemGroups(tempItemList , c => c.ItemCategory.ID + "|" + c.ItemCategory.Name + "|" + c.ItemCategory.IMPath);
    }

    private static ObservableCollection<Group<T>> GetItemGroups<T>(IEnumerable<T> itemList, Func<T, string> getKeyFunc)
    {
        IEnumerable<Group<T>> groupList = from item in itemList
                                          group item by getKeyFunc(item) into g
                                          orderby g.Key
                                          select new Group<T>(g.Key, g);

        //return groupList.ToList();
        ObservableCollection<Group<T>> t = new ObservableCollection<Group<T>>();
        foreach (Group<T> sublist in groupList)
        {
            t.Add(sublist);
        }

        return t;
    }

我如何处理删除:

        this.cartList.Remove(editingCartItem);

        ObservableCollection<Group<ItemClass>> t = (ObservableCollection<Group<ItemClass>>)LongListSelectorObj.ItemsSource;

        foreach (Group<ItemClass> sublist in t)
        {
            if(sublist.Contains(editingItem))
                sublist.Remove(editingItem);
            break;
        }

这有点臃肿,因为我最近进行了更改以尝试将所有内容都设为 ObservableCollection,并认为它可以解决我当时的问题。它确实对其他事情有所帮助,但我认为这归结为列表不同。

我想我可以将其更改为直接绑定 ObservableCollection>,但我相信我会失去简单的添加/排序,对吧?

另外,我认为问题可能是因为我试图从两个单独的列表中删除该项目。但是,我只尝试了一个,但我仍然遇到相同的异常问题,我认为这是来自演员表(即能够删除所有内容,直到倒数第二个,然后是最后一个项目)。

非常感谢任何收到的帮助。

【问题讨论】:

    标签: windows-phone-8 observablecollection longlistselector


    【解决方案1】:

    如果您正确实现了 ViewModel,那么从 ObservableCollection 中移除 T 对象确实会从 LLS 的 ItemsSource 中移除它!当集合被修改时,ObservableCollection 将触发 CollectionChanged 事件,因为它继承自 INotifyCollectionChanged 接口。

    我肯定会阅读 MVVM 策略,因为您的实现看起来有问题。

    至于你目前的解决方案,

    您有几个拼写错误。我会下载 ReSharper,它可以非常快速地为您指出这些问题。像这样的东西:

    • &lt;ITemClass&gt; // 大写T
    • private ObservableCollection&lt;Model.Cartitem&gt; cartList = new ObservableCollection&lt;Model.allItems&gt;(); // Model.Carditem 与 Model.allItems?

    如果您认为这是一个强制转换问题,那么每次尝试访问类属性时检查您的 null 语句是非常明智的。使用as 语法(link) 也很好,它有助于进行空检查。

    DataType data = value as DataType; 
    if (data != null) {
        string title = data.Title;
    }
    

    对于这一行,

    this.cartList.Remove(editingCartItem);
    

    试着把它变成这样:

    if (editingCardItem != null && this.cardList.Contains(editingCartItem)){
        this.cardList.Remove(editingCardItem);
    }
    

    另外,您的sublist 是否应该删除editingItemeditingCardItem?请牢记这些事项。

    否则,我会清理您的代码,但如果不深入,我看不到任何其他明显的问题,因为您的代码有点过头了,而且很难解析语法。祝你好运!

    【讨论】:

    • 感谢您的注释,我确实在我的副本中做了一些糟糕的编辑并粘贴到这里(缩短了所有名称),但仍然会得到 Reshaper。并将尝试您所建议的大部分内容。我在了解它之前很久就开始使用字符串 MVVM 模式,然后被告知对于一个简单的应用程序(比如两页)我并不真正需要它,所以我没有尝试更改。我应该吗?
    猜你喜欢
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多