Search code examples
xamarin.formsdatatriggeribindabletemplate

Hide Xamarin Forms StackLayout if Binding array has no items


In my Xamarin Forms app, I have a CarouselView to swipe through messages. Some messages have attachments. I would like to hide the StackLayout attachmentsLayout when the Attachments list has no items.

I tried to play with DataTriggers but it did not work.

<?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:local="clr-namespace:MyApp.Helpers" x:Class="MyApp.MailboxConversationPage" Title="Messages">
    <ContentPage.Content>
        <AbsoluteLayout x:Name="absLayout" VerticalOptions="FillAndExpand">
            <StackLayout HorizontalOptions="Fill" HeightRequest="{Binding Path=Height, Source={x:Reference absLayout}}" WidthRequest="{Binding Path=Width, Source={x:Reference absLayout}}">
                <StackLayout VerticalOptions="Start" Padding="10,10,10,5">
                  <Label x:Name="Subject" Text="Subject" FontSize="Large" FontAttributes="Bold" />
                </StackLayout>
                <StackLayout x:Name="carouselViewLayout" VerticalOptions="FillAndExpand">
                    <ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" HeightRequest="{Binding Path=Height, Source={x:Reference carouselViewLayout}}" WidthRequest="{Binding Path=Width, Source={x:Reference carouselViewLayout}}">
                      <CarouselView x:Name="CarouselMessages" PositionChanged="OnPositionChanged">
                        <CarouselView.ItemTemplate>
                          <DataTemplate>
                            <StackLayout HorizontalOptions="Fill" BackgroundColor="#f5f5f5">
                              <StackLayout VerticalOptions="Start" Padding="10,10,10,5">
                                <Label Text="{Binding Sender}" FontAttributes="Bold" />
                              </StackLayout>
                              <StackLayout VerticalOptions="FillAndExpand" Padding="10,10,10,10" BackgroundColor="White">
                                <ScrollView>
                                    <Label Text="{Binding Body}" />
                                </ScrollView>
                              </StackLayout>
                              <StackLayout x:Name="attachmentsLayout" BindableLayout.ItemsSource="{Binding Attachments}" VerticalOptions="End" Padding="10,10,10,10" BackgroundColor="White">
                                <BindableLayout.ItemTemplate>
                                    <DataTemplate>
                                        <Label>
                                            <Label.FormattedText>
                                                <FormattedString>
                                                    <local:HyperlinkSpan Text="{Binding Filename}" Url="{Binding Url}" />
                                                </FormattedString>
                                            </Label.FormattedText>
                                        </Label>
                                    </DataTemplate>
                                 </BindableLayout.ItemTemplate>
                              </StackLayout>
                              <StackLayout VerticalOptions="End" Padding="10,5,10,10">
                                <Label Text="{Binding Created_At}" BackgroundColor="#f5f5f5" />
                              </StackLayout>
                            </StackLayout>
                          </DataTemplate>
                        </CarouselView.ItemTemplate>
                      </CarouselView>
                    </ContentView>
                </StackLayout>
                <StackLayout x:Name="editorLayout" VerticalOptions="FillAndExpand" IsVisible="false" Padding="10,0,10,0">
                    <Frame x:Name="replyFrame" HeightRequest="{Binding Path=Height, Source={x:Reference editorLayout}}" HasShadow="false" OutlineColor="Gray" Padding="2,0,2,0">
                    <Editor x:Name="replyEditor">
                        <Editor.BackgroundColor>
                            <OnPlatform x:TypeArguments="Color"
                                iOS="White"
                                Android="Transparent"
                                WinPhone="#2c3e50" />
                        </Editor.BackgroundColor>
                    </Editor>
                    </Frame>
                </StackLayout>
                <StackLayout VerticalOptions="End" Padding="10,3,10,10">
                    <Button x:Name="replyButton" Text="Reply" Clicked="OnReplyActivated" BorderRadius="5" BackgroundColor="#337ab7" TextColor="White" FontAttributes="Bold" />
                    <Button x:Name="sendButton" Text="Send Message" Clicked="OnSendMessageActivated" BorderRadius="5" BackgroundColor="#337ab7" TextColor="White" FontAttributes="Bold" IsVisible="false"/>
                </StackLayout>
            </StackLayout>
            <ContentView x:Name="overlay" AbsoluteLayout.LayoutBounds="0, 0, 1, 1"  AbsoluteLayout.LayoutFlags="All" IsVisible="True" BackgroundColor="#C0808080" Padding="10, 0">
                <ActivityIndicator  WidthRequest="110" HeightRequest="70" IsRunning="True" IsVisible="True" Color="Black" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
            </ContentView>
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage>

Solution

  • Why don't you simply add another property to your ViewModel that indicates whether there are any items in your Attachments collection. Then bind IsVisible of the layout to this property

    View

    <StackLayout x:Name="attachmentsLayout" 
                 IsVisible="{Binding HasItems}"
                 BindableLayout.ItemsSource="{Binding Attachments}"
                 VerticalOptions="End" Padding="10,10,10,10" BackgroundColor="White">
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <Label>
                <Label.FormattedText>
                    <FormattedString>
                        <local:HyperlinkSpan Text="{Binding Filename}" Url="{Binding Url}" />
                    </FormattedString>
                </Label.FormattedText>
            </Label>
        </DataTemplate>
    </BindableLayout.ItemTemplate>
    </StackLayout>
    

    ViewModel

    public bool HasItems => Attachments.Any();