Xamarin和Prism的可扩展Listview

时间:2017-07-12 14:24:25

标签: xamarin.forms prism

我想创建一个可扩展的列表视图,我跟随这个例子:

Example

问题是我使用Prism作为MVVM框架,所以我不能使用事件,我使用命令。 这是代码:

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:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
         prism:ViewModelLocator.AutowireViewModel="True"
         x:Class="JDeliveryCP.Views.DocumentsPage"
         x:Name="TheDocumentsPage">
<ContentPage.Content>
    <ListView x:Name="lstDocuments" GroupDisplayBinding="{Binding Title}" RowHeight="75" IsGroupingEnabled="True" ItemsSource="{Binding ExpandedDocuments}" >
        <ListView.GroupHeaderTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Orientation="Horizontal" >
                        <ContentView>

                            <Grid x:Name="cell">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="1*" />
                                </Grid.ColumnDefinitions>
                                <Label Text="{Binding Title}"/>

                                <ContentView.GestureRecognizers>
                                    <TapGestureRecognizer Command="{Binding HeaderTappedCommand}" BindingContext="{Binding Source={x:Reference lstDocuments}, Path=BindingContext}" 
                                                  CommandParameter="{Binding Source={x:Reference cell}, Path=BindingContext}" />
                                </ContentView.GestureRecognizers>
                            </Grid>
                        </ContentView>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.GroupHeaderTemplate>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ImageCell Text="{Binding Description}" ImageSource="icon.png" Height="75" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage.Content>

PageViewModel:

using JDeliveryCP.FEModels;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using Xamarin.Forms;

namespace JDeliveryCP.ViewModels
{
    public class DocumentsPageViewModel : BindableBase, INotifyPropertyChanged
    {
        private ObservableCollection<DocumentGroupModel> _documents;
        private ObservableCollection<DocumentGroupModel> _expandedDocuments;
        private ICommand headerTappedCommand;
    public ICommand HeaderTappedCommand
    {
        get { return headerTappedCommand; }
    }

    public ObservableCollection<DocumentGroupModel> Documents
    {
        get { return _documents; }
        set { SetProperty(ref _documents, value); }
    }

    public ObservableCollection<DocumentGroupModel> ExpandedDocuments
    {
        get { return _expandedDocuments; }
        set { SetProperty(ref _expandedDocuments, value); }
    }

    public DocumentsPageViewModel()
    {

        headerTappedCommand = new Command(HeaderTapped);
        //TEST -START-
        _documents = new ObservableCollection<DocumentGroupModel>
        {
            new DocumentGroupModel(897, "Cliente 1", false)
            {
                    new DocumentModel { Description = "documento 1"},
                    new DocumentModel { Description = "documento 2"},
                    new DocumentModel { Description = "documento 3"}
            },
            new DocumentGroupModel(543, "Cliente 2", false)
            {
                    new DocumentModel { Description = "documento 4"},
                    new DocumentModel { Description = "documento 5"}
            }
        };
        //TEST -END-

        UpdateListContent();
    }

    async void HeaderTapped(object sender, EventArgs args)
    {
        HeaderTapped(sender);
    }

        private void HeaderTapped(object sender)
    {
        DocumentGroupModel selected = ((DocumentGroupModel)(sender));
        DocumentGroupModel found = _documents.FirstOrDefault(x => x.Id == selected.Id);
        found.Expanded = !found.Expanded;       
        UpdateListContent();
        OnPropertyChanged(new PropertyChangedEventArgs("Expanded"));
    }


    private void UpdateListContent()
    {

        _expandedDocuments = new ObservableCollection<DocumentGroupModel>();
        foreach(DocumentGroupModel group in _documents)
        {
            DocumentGroupModel newGroup = new DocumentGroupModel(group.Id, group.Title, group.Expanded);

            if (group.Expanded)
            {
                foreach(DocumentModel doc in group)
                {                        
                    newGroup.Add(doc);
                }
            }
            _expandedDocuments.Add(newGroup);
        }            

    }

}

}

GROUP MODEL:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JDeliveryCP.FEModels
{
    public class DocumentGroupModel : ObservableCollection<DocumentModel>, INotifyPropertyChanged
    {
        private bool _expanded;

        public string Title { get; set; }

        public int Id { get; set; }

        public bool Expanded
        {
            get { return _expanded; }
            set
            {
                if (_expanded != value)
                {
                    _expanded = value;                  
                    OnPropertyChanged(new PropertyChangedEventArgs("Expanded"));                 
                }
            }
        }

        public DocumentGroupModel(int id, string title, bool expanded = true)
        {
            Id = id;
            Title = title;
            Expanded = expanded;
        }
    }
}

项目模型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JDeliveryCP.FEModels
{
    public class DocumentModel
    {
        public string Description { get; set; }


    }
}

Listview被正确渲染并且点击命令有效,但它没有显示被点击组的行,布局没有改变。我试图调试&#34; HeaderTapped&#34;方法和组正确填充。我不知道它是否可能是小部件刷新的问题或行模型和pageviewmodel之间的绑定问题。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我自己解决了这个问题。

我改变了这个:

    private void HeaderTapped(object sender)
    {
        DocumentGroupModel selected = ((DocumentGroupModel)(sender));
        DocumentGroupModel found = _documents.FirstOrDefault(x => x.Id == selected.Id);
        found.Expanded = !found.Expanded;       
        UpdateListContent();
        OnPropertyChanged(new PropertyChangedEventArgs("Expanded"));
    }

用这个:

        private void HeaderTapped(object sender)
        {
            DocumentGroupModel selected = ((DocumentGroupModel)(sender));
            DocumentGroupModel found = _documents.FirstOrDefault(x => x.Id == selected.Id);
            found.Expanded = !found.Expanded;       
            UpdateListContent();
            OnPropertyChanged(new PropertyChangedEventArgs("ExpandedDocuments"));
        }

所以我只更改了&#34; OnPropertyChanged&#34;参数。