FlexLayout LeftToRight with Wrapping and selectable items?

Da'ud Vyd 21 Reputation points

Hi folks,

I'd like to use FlexLayout to display the contents of an ObservableCollection<string> horizontally and wrap them. The items will be selectable (one at a time). I'm familiar with Picker, which permits binding to an ObservableCollection and tells me what the user selected. But FlexLayout appears to require manually adding items via C# (e.g. thisflexlayout.Children.Add(new...)). So if I add buttons, I would then use their Clicked or Command property instead of the way Picker uses SelectedItem. Is this the only way to proceed? Or is there a way to put a DataTemplate inside the FlexLayout somehow and use a single button tag to define how all items in the collection should be displayed and then use CommandParameter on the button to differentiate between them?

This is what I want to do, visually, but generate the buttons via data binding if possible:

<FlexLayout x:Name="layout" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="4" Wrap="Wrap" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand">
            <Button Text="Tag_1" WidthRequest="80"/>
            <Button Text="Tag_2 ...." WidthRequest="140"/>
            <Button Text="Tag_3" WidthRequest="70"/>
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,301 questions
0 comments No comments
{count} votes

Accepted answer
  1. JarvanZhang 23,951 Reputation points


    Welcome to our Microsoft Q&A platform!

    For this function, try using Bindable layout which enables the layout class generate its content by binding to a collection of items.

       <FlexLayout BindableLayout.ItemsSource="{Binding DataCollection}"  

    Here is the related doc, you could refer to it.

    Best Regards,

    Jarvan Zhang

    If the response is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Da'ud Vyd 21 Reputation points

    As I mentioned in my comment above, my command no longer works and was working fine with buttons manually built in XAML. Previously, I had an unbound FlexLayout containing buttons like this:

    <Button x:Name="WalkButton" Text="Move" Grid.Row="3" Grid.Column="0" Command="{Binding DoAction}" CommandParameter="Walk"/>
    <Button x:Name="RunButton" Text="Talk" Grid.Row="3" Grid.Column="1" Command="{Binding DoAction}" CommandParameter="Run"/>

    Now I bind to "Moves", an ObservableCollection<string>:

        <FlexLayout BindableLayout.ItemsSource="{Binding Moves}" Wrap="Wrap" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand">
                    <Button x:Name="{Binding}" Text="{Binding}" Command="{Binding DoAction}" CommandParameter="{Binding}"/>

    The buttons look great (thanks!)...but...they do nothing when pressed. Upon stopping the application, the Console reports:

    [0:] Binding: 'DoAction' property not found on 'walk', target property: 'Xamarin.Forms.Button.Command'
    [0:] Binding: 'DoAction' property not found on 'walk', target property: 'Xamarin.Forms.Button.Command'
    [0:] Binding: 'DoAction' property not found on 'run', target property: 'Xamarin.Forms.Button.Command'
    [0:] Binding: 'DoAction' property not found on 'run', target property: 'Xamarin.Forms.Button.Command'
    [0:] Binding: 'DoAction' property not found on 'climb', target property: 'Xamarin.Forms.Button.Command'
    [0:] Binding: 'DoAction' property not found on 'climb', target property: 'Xamarin.Forms.Button.Command'

    I expected this to work without modifying DoAction in my ViewModel because CommandParameter="{Binding}" should send "walk", "run", etc as an argument just like before. Weird that each Binding error is reported twice, right? Also, my can execute code stopped working:

    void RefreshCanExecutes()
                (DoAction as Command).ChangeCanExecute();

    I really do like the BindableLayout.ItemsSource approach so I want to modify my code accordingly. But, I don't understand how adding a binding to the FlexLayout could have caused the C# code to stop working. (and if that really can't be the reason...well I have some real digging to do!)