Anton Duzenko
Anton Duzenko

Reputation: 2596

Xamarin.Forms: expandable layout?

I was tasked with converting an existing "static" vertical layout with some kind of expandable. Here's the expected result.

enter image description here

I understand the XF framework does not have anything like this out of the box. The question is how to create a custom control that would embed all kinds of other controls. Please note that child control can be anything, including another layout with multiple children.

I want something like XF master-detail page in terms of configuration. E.g.

<ThisNewControl Caption="Description">
  <ThisNewControl.Content>
     <Entry Text="{Binding Description}"/>
  <ThisNewControl.Content>
</ThisNewControl>

<ThisNewControl Caption="More Stuff">
  <ThisNewControl.Content>
     <StackLayout>
...
     </StackLayout>
  <ThisNewControl.Content>
</ThisNewControl>

Upvotes: 1

Views: 1363

Answers (2)

chri3g91
chri3g91

Reputation: 1410

Xamarin.Forms 4.6+ has introduced the Expander element Microsoft docs, thanks to Community member Andrei Misiukevich. Although, it is currently experimental (requires setting the Expander_Experimental flag), my experience with it has been very positive.

Upvotes: 0

Anton Duzenko
Anton Duzenko

Reputation: 2596

Here's what I ended up with

using Xamarin.Forms;

namespace SmartwebsCrossPlatform.Portable.Controls {
    class ExpandableGrid : Grid {
        static readonly Thickness IconMargin = new Thickness(9, 0);

        View content;
        public View Content {
            get => content;
            set {
                content = value;
                Children.Add( value, 0, 1 );
            }
        }

        Label lblDesc = new Label();
        Label icon = new Label { Text = ">", Margin = IconMargin, HorizontalOptions = LayoutOptions.End };

        public string Caption {
            set {
                lblDesc.Text = value;
            }
        }

        public ExpandableGrid() {
            RowDefinitions = new RowDefinitionCollection {
                new RowDefinition { Height = GridLength.Auto },
                new RowDefinition { Height = 0 },
            };
            ColumnDefinitions = new ColumnDefinitionCollection {
                new ColumnDefinition { Width = GridLength.Star },
            };
            Children.Add( lblDesc, 0, 0 );
            Children.Add( icon, 0, 0 );
            lblDesc.GestureRecognizers.Add( new TapGestureRecognizer { Command = new Command( LabelClick ) } );
        }

        void LabelClick() {
            if( RowDefinitions[1].Height.IsAuto ) {
                RowDefinitions[1].Height = 0;
                icon.Text = ">";
            } else {
                RowDefinitions[1].Height = GridLength.Auto;
                icon.Text = "v";
            }
        }
    }
}

XAML use:

<controls:ExpandableGrid Caption="Additional Details">
  <controls:ExpandableGrid.Content>
    <Entry Text="{Binding AdditionalDetail}"/>
  </controls:ExpandableGrid.Content>
</controls:ExpandableGrid>

Upvotes: 2

Related Questions