Mvvm 更改ObservableCollection时,FlowListView未完全更新UI<;T>;

Mvvm 更改ObservableCollection时,FlowListView未完全更新UI<;T>;,mvvm,xamarin.forms,observablecollection,Mvvm,Xamarin.forms,Observablecollection,当我从列表中删除对象时,UI不会反映列表的当前状态,通常只有一个项目出现故障 示例:如果我删除了4项,则在UI上仅显示我删除了3项 private ObservableCollection<Card> _cards; public ObservableCollection<Card> Cards { get { if (_cards == null) {

当我从列表中删除对象时,UI不会反映列表的当前状态,通常只有一个项目出现故障

示例:如果我删除了4项,则在UI上仅显示我删除了3项

 private ObservableCollection<Card> _cards;

    public ObservableCollection<Card> Cards
    {
        get
        {
            if (_cards == null)
            {
                _cards = new ObservableCollection<Card>();
                return _cards;
            }

            return _cards;
        }
        set
        {
            SetValue(ref _cards, value);
        }
    }
我在FlowListView中的绑定

<controls:FlowListView x:Name="Board" HasUnevenRows="True"
                               BackgroundColor="Black"
                               FlowColumnCount="2"
                               FlowItemTappedCommand="{Binding ExecuteActionCommand}"
                               FlowColumnMinWidth="110"
                               IsPullToRefreshEnabled="True"
                               IsRefreshing="{Binding IsRefreshing}"
                               RefreshCommand="{Binding RefreshViewCommand}"
                               FlowItemsSource="{Binding Cards}"> .....
。。。。。

提前感谢各位

请确保在property语句中的SetValue()之后正确触发PropertyChanged

尝试使用这个类(来自xamarin)并传递card的ienumerable,而不是card-only对象

范例

private void RemoveFromCards(Card card)
{
    Cards.RemoveRange(new []{card});
}

//or directly from

private void RemoveCardsFromView(List<Archive> cards)
{
    Cards.RemoveRange(cards.Select(s=> new Card {Id = a.CardId}));
} 

/// <summary> 
/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public class ObservableRangeCollection<T> : ObservableCollection<T>
{

    /// <summary> 
    /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. 
    /// </summary> 
    public ObservableRangeCollection()
        : base()
    {
    }

    /// <summary> 
    /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. 
    /// </summary> 
    /// <param name="collection">collection: The collection from which the elements are copied.</param> 
    /// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception> 
    public ObservableRangeCollection(IEnumerable<T> collection)
        : base(collection)
    {
    }

    /// <summary> 
    /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). 
    /// </summary> 
    public void AddRange(IEnumerable<T> collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Add)
    {
        if (collection == null)
            throw new ArgumentNullException("collection");

        CheckReentrancy();

        if (notificationMode == NotifyCollectionChangedAction.Reset)
        {
            foreach (var i in collection)
            {
                Items.Add(i);
            }

            OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

            return;
        }

        int startIndex = Count;
        var changedItems = collection is List<T> ? (List<T>)collection : new List<T>(collection);
        foreach (var i in changedItems)
        {
            Items.Add(i);
        }

        OnPropertyChanged(new PropertyChangedEventArgs("Count"));
        OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItems, startIndex));
    }

    /// <summary> 
    /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). 
    /// </summary> 
    public void RemoveRange(IEnumerable<T> collection)
    {
        if (collection == null)
            throw new ArgumentNullException("collection");

        foreach (var i in collection)
            Items.Remove(i);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    /// <summary> 
    /// Clears the current collection and replaces it with the specified item. 
    /// </summary> 
    public void Replace(T item)
    {
        ReplaceRange(new T[] { item });
    }

    /// <summary> 
    /// Clears the current collection and replaces it with the specified collection. 
    /// </summary> 
    public void ReplaceRange(IEnumerable<T> collection)
    {
        if (collection == null)
            throw new ArgumentNullException("collection");

        Items.Clear();
        AddRange(collection, NotifyCollectionChangedAction.Reset);
    }
}
private void RemoveFromCards(卡片)
{
Cards.RemoveRange(新[]{card});
}
//或者直接从
私有作废移除卡片浏览(列表卡)
{
Cards.RemoveRange(Cards.Select(s=>newcard{Id=a.cardd}));
} 
///  
///表示动态数据集合,该集合在添加、删除项或刷新整个列表时提供通知。
///  
///  
公共类ObserverAgeCollection:ObserverCollection
{
///  
///初始化System.Collections.ObjectModel.ObservableCollection(of T)类的新实例。
///  
公共ObserverAgeCollection()
:base()
{
}
///  
///初始化System.Collections.ObjectModel.ObservableCollection(of T)类的新实例,该类包含从指定集合复制的元素。
///  
///集合:从中复制元素的集合。
///集合参数不能为null。
公共ObserverAgeCollection(IEnumerable集合)
:基本(集合)
{
}
///  
///将指定集合的元素添加到ObservableCollection(of T)的末尾。
///  
public void AddRange(IEnumerable集合,NotifyCollectionChangedAction notificationMode=NotifyCollectionChangedAction.Add)
{
if(集合==null)
抛出新的ArgumentNullException(“集合”);
检查可重入性();
if(notificationMode==NotifyCollectionChangedAction.Reset)
{
foreach(集合中的变量i)
{
项目.添加(i);
}
OnPropertyChanged(新PropertyChangedEventArgs(“计数”);
OnPropertyChanged(新的PropertyChangedEventArgs(“项目[]”);
OnCollectionChanged(新建NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
返回;
}
int startIndex=计数;
var changedItems=集合是列表?(列表)集合:新列表(集合);
foreach(changedItems中的变量i)
{
项目.添加(i);
}
OnPropertyChanged(新PropertyChangedEventArgs(“计数”);
OnPropertyChanged(新的PropertyChangedEventArgs(“项目[]”);
OnCollectionChanged(新的NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add、changedItems、startIndex));
}
///  
///从ObservableCollection(of T)中删除指定集合中每个项的第一次出现。
///  
公共无效删除范围(IEnumerable集合)
{
if(集合==null)
抛出新的ArgumentNullException(“集合”);
foreach(集合中的变量i)
删除第(i)项;
OnCollectionChanged(新建NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
///  
///清除当前集合并将其替换为指定项。
///  
公共无效替换(T项)
{
替换范围(新的T[]{item});
}
///  
///清除当前集合并将其替换为指定集合。
///  
公共void ReplaceRange(IEnumerable集合)
{
if(集合==null)
抛出新的ArgumentNullException(“集合”);
Items.Clear();
AddRange(collection,NotifyCollectionChangedAction.Reset);
}
}

如何计算“RemoveCardsFromView”函数中的参数“cards”?输入你的电话号码please@safi我就是这么叫它的。每个归档文件都有一个Id引用,指向ObservableCollections上的卡。请记住,此错误并非总是发生。老实说,我不知道这次可观测到的数据是怎么回事。我的猜测是FlowListView中的绑定有问题,但我搜索了他们的论坛,似乎并没有人给出答案,我会试试。你能告诉我这个类和ObservableCollection在被通知方面有什么区别吗?Items.Remove(i)对我不起作用,它与比较有关。这就是为什么我在自己做比较时使用RemoveAt(索引)的原因我知道,但是在那次更改之后,代码在其他地方开始崩溃,我放弃了这个想法,自己做了比较。我将尝试againI多次尝试测试它,当我删除1个元素时,它有2个元素时,项目会得到更新,但UI仍保留2个元素
 public async Task RefreshCardsView()
    {
        if (!CrossConnectivity.Current.IsConnected)
        {
            BuildToast(false,"No internet connection");
            return;
        }

        try
        {
            JsonResult cards = (JsonResult) await HttpMiddleman.GetCards();
            RemoveCardsFromView(cards.Data.DeletedCards);
            AddCardsToView(cards.Data.AddedCards);
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.Message);
            BuildToast(false,"Could not refresh");
        }               
    }
<controls:FlowListView x:Name="Board" HasUnevenRows="True"
                               BackgroundColor="Black"
                               FlowColumnCount="2"
                               FlowItemTappedCommand="{Binding ExecuteActionCommand}"
                               FlowColumnMinWidth="110"
                               IsPullToRefreshEnabled="True"
                               IsRefreshing="{Binding IsRefreshing}"
                               RefreshCommand="{Binding RefreshViewCommand}"
                               FlowItemsSource="{Binding Cards}"> .....
private void RemoveFromCards(Card card)
{
    Cards.RemoveRange(new []{card});
}

//or directly from

private void RemoveCardsFromView(List<Archive> cards)
{
    Cards.RemoveRange(cards.Select(s=> new Card {Id = a.CardId}));
} 

/// <summary> 
/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public class ObservableRangeCollection<T> : ObservableCollection<T>
{

    /// <summary> 
    /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. 
    /// </summary> 
    public ObservableRangeCollection()
        : base()
    {
    }

    /// <summary> 
    /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. 
    /// </summary> 
    /// <param name="collection">collection: The collection from which the elements are copied.</param> 
    /// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception> 
    public ObservableRangeCollection(IEnumerable<T> collection)
        : base(collection)
    {
    }

    /// <summary> 
    /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). 
    /// </summary> 
    public void AddRange(IEnumerable<T> collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Add)
    {
        if (collection == null)
            throw new ArgumentNullException("collection");

        CheckReentrancy();

        if (notificationMode == NotifyCollectionChangedAction.Reset)
        {
            foreach (var i in collection)
            {
                Items.Add(i);
            }

            OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

            return;
        }

        int startIndex = Count;
        var changedItems = collection is List<T> ? (List<T>)collection : new List<T>(collection);
        foreach (var i in changedItems)
        {
            Items.Add(i);
        }

        OnPropertyChanged(new PropertyChangedEventArgs("Count"));
        OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItems, startIndex));
    }

    /// <summary> 
    /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). 
    /// </summary> 
    public void RemoveRange(IEnumerable<T> collection)
    {
        if (collection == null)
            throw new ArgumentNullException("collection");

        foreach (var i in collection)
            Items.Remove(i);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    /// <summary> 
    /// Clears the current collection and replaces it with the specified item. 
    /// </summary> 
    public void Replace(T item)
    {
        ReplaceRange(new T[] { item });
    }

    /// <summary> 
    /// Clears the current collection and replaces it with the specified collection. 
    /// </summary> 
    public void ReplaceRange(IEnumerable<T> collection)
    {
        if (collection == null)
            throw new ArgumentNullException("collection");

        Items.Clear();
        AddRange(collection, NotifyCollectionChangedAction.Reset);
    }
}