1
votes

I have a StackLayout with Bindable Layout ItemSource set, the stacklayout's datatemplate contains an Expander View (available in Xamarin Forms 4.7), my requirement is on clicking Expander header, dynamic data should be loaded and displayed in Expander body, for that, I'm using a pancakeview to which another Bindable Layout ItemSource is set and this is handled in code behind.

Basically what I'm trying to achieve is there is a list, which gets populated on the page open, On clicking any item it should expand and show additional data, which is loaded from server on Expander header click.

What is the best way to achieve this? below is what I have done so far:

<StackLayout x:Name="StudentsStack" BindableLayout.ItemsSource="{Binding StudentData}" Margin="10" 
                             HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<BindableLayout.ItemTemplate>
    <DataTemplate>
        <Expander Tapped="StudentsClicked" ExpandAnimationEasing="{x:Static Easing.CubicIn}" ExpandAnimationLength="200" CollapseAnimationEasing="{x:Static Easing.CubicOut}" CollapseAnimationLength="200" HorizontalOptions="FillAndExpand">
            <Expander.Header>
                <Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" RowDefinitions="*" ColumnDefinitions="*">
                    <local:MarqueeLabel FontAttributes="Bold" FontSize="20" HorizontalOptions="Start" Text="{Binding Name}" TextColor="Black" XAlign="Start" FontFamily="googlesansbold"/>
                    <Label IsVisible="False" Text="{Binding Id}"/>
                </Grid>
            </Expander.Header>
            <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
                <pv:PancakeView BindableLayout.ItemsSource="{Binding StudentDetails}" HeightRequest="30" Margin="5" Padding="5" HasShadow="False"  HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" CornerRadius="5"  BackgroundColor="White">
                    <pv:PancakeView.Shadow>
                        <pv:DropShadow Opacity="0.1" />
                    </pv:PancakeView.Shadow>
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <Grid Margin="0" ColumnDefinitions="*,*" RowDefinitions="*" HorizontalOptions="FillAndExpand">
                                <Label Grid.Row="0" Grid.Column="0" FontAttributes="Bold" FontSize="14" HorizontalOptions="Center" Text="{Binding rank}" TextColor="Black" XAlign="Start" FontFamily="googlesansbold" VerticalTextAlignment="Center" Padding="5,0,0,5"/>
                                <Label Grid.Row="0" Grid.Column="1" FontAttributes="Bold" FontSize="14" HorizontalOptions="Center" Text="{Binding address}" TextColor="Green" XAlign="Start" FontFamily="googlesansbold" VerticalTextAlignment="Center" Padding="5,0,0,5"/>
                            </Grid>
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </pv:PancakeView>
            </StackLayout>
        </Expander>
    </DataTemplate>
</BindableLayout.ItemTemplate>

In the code behind

public ObservableCollection<Student> StudentData{ get; } = new ObservableCollection<Student>();
public ObservableCollection<Detail> StudentDetails{ get; } = new ObservableCollection<Detail>();

and inside page constructor, I'm doing this

BindingContext = this;

Binding is working fine for "StudentData" list is being populated, but what is the best approach to generate additional data on expander expanded?

1

1 Answers

1
votes

You could use List in List .

in class Student

public class Student
    {
        public ObservableCollection<Detail> StudentDetails { get; } 

        public Student (ObservableCollection<Detail> studentDetails)
        {
            StudentDetails = studentDetails;
        }

        //...other properties
    }

And in code behind

StudentData = new ObservableCollection<Student>(){

 new Student(new ObservableCollection<Detail>()){//...other properties},
 //...

};