如何从ListView更新组头?

时间:2017-09-22 11:28:00

标签: c# listview xamarin.forms observablecollection

我正在移除ListView中的内容。因为我也在组头中使用计数器,所以我必须更新它。但是我怎么能这样做呢?这是我的代码:

ListView

<ListView x:Name="MyListList"
    HasUnevenRows="True" 
    CachingStrategy="RecycleElement" 
    IsGroupingEnabled="True" 
    GroupDisplayBinding="{Binding Key}" 
    IsPullToRefreshEnabled="True"
    RefreshCommand="{Binding LoadDataCommand}"
    IsRefreshing="{Binding IsRefreshing, Mode=OneWay}">

    <ListView.GroupHeaderTemplate>
        <DataTemplate>
            <customViews:MyGroupingHeaderCell/>
        </DataTemplate>
    </ListView.GroupHeaderTemplate>

    <ListView.ItemTemplate>
        <DataTemplate>
            <customViews:MyHeaderCell />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

自定义组标题:

<?xml version="1.0" encoding="utf-8" ?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
          xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
          x:Class="Views.MyGroupingHeaderCell"
          xmlns:customViews="clr-namespace:Views;"
          xmlns:renderer="clr-namespace:Common.CustomRenderers;">
    <renderer:ListViewGroupHeader x:Name="keyName" Style="{StaticResource labelHeader}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</ViewCell>
public partial class MyGroupingHeaderCell : ViewCell
{
    public MyGroupingHeaderCell()
    {
        InitializeComponent();
    }

    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();
        var item = BindingContext as ObservableGroupCollection<string, CustomObject>;
        if (item != null)
        {
            this.keyName.Text = item.Key + " (" + item.Count + ")";
        }
        else
        {
            this.keyName.Text = string.Empty;
        }
    }
}

我使用此LINQ表达式为项目创建Key

List<ObservableGroupCollection<string, CustomObject>> resultList = rawList.OrderByWithDirection(order, descending)
                                                                            .GroupBy(group)
                                                                            .Select(p => new ObservableGroupCollection<string, CustomObject>(p))
                                                                            .OrderByWithDirection(i => i.Key, false) // sort the group
                                                                            .ToList();

其中group

Func<CustomObject, string> group = p => p.SomeObject.Identification;

可能的解决方案:

我现在正在做的是,我通过从原始数据中删除项目并重新设置ListView来完全重新加载ItemSource。这不是一个真正的性能解决方案,但它确实有效。 ObservableCollection的优势已经消失了。

1 个答案:

答案 0 :(得分:1)

假设ObservableGroupCollection实现INotifyCollectionChanged - 我们可以订阅集合更改事件。为此,添加可绑定属性会更容易,因为它更容易跟踪属性更改,因此可以订阅/取消订阅事件。

public partial class MyGroupingHeaderCell : ViewCell
{
    public static readonly BindableProperty CollectionProperty =
        BindableProperty.Create(
            "Collection", typeof(INotifyCollectionChanged), typeof(MyGroupingHeaderCell),
            defaultValue: default(INotifyCollectionChanged), propertyChanged: OnCollectionChanged);

    public INotifyCollectionChanged Collection
    {
        get { return (INotifyCollectionChanged)GetValue(CollectionProperty); }
        set { SetValue(CollectionProperty, value); }
    }

    private static void OnCollectionChanged(BindableObject bindable, object oldValue, object newValue)
    {
        ((MyGroupingHeaderCell)bindable).OnCollectionChangedImpl((INotifyCollectionChanged)oldValue, (INotifyCollectionChanged)newValue);
    }

    protected virtual void OnCollectionChangedImpl(INotifyCollectionChanged oldValue, INotifyCollectionChanged newValue)
    {
        if(oldValue != null)
            oldValue.CollectionChanged -= OnCollectionChanged;
        if(newValue != null)
            newValue.CollectionChanged += OnCollectionChanged;

        OnCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        var item = BindingContext as ObservableGroupCollection<string, CustomObject>;
        if (item != null)
        {
            this.keyName.Text = item.Key + " (" + item.Count + ")";
        }
        else
        {
            this.keyName.Text = string.Empty;
        }
    }
}

并且,XAML用法将更改为:

<ListView.ItemTemplate>
    <DataTemplate>
        <customViews:MyHeaderCell Collection="{Binding}" />
    </DataTemplate>
</ListView.ItemTemplate>