1
votes

I've been working on creating a custom control for some time. After several iterations I've come to the conclusion that I am having a binding issue... As it is, when I place my control into a simple XAML page and execute the feature, it works just fine. However, when I need to instantiate numerous controls on a single page, i.e. into a collection, flexlayout, carouselview the Command and CommandParameter bindings get lost... and the ViewModel calls no longer occur.

My control is simple... think of a checkbox replacement. I place A 1x1 grid, with a frame (for the outline) and a label to place a single character... "A", "B", "C"... "1". "2". "3"... whatever you would require... I have bindable properties.. Text, TextColor, BorderColor, BackgroundColor, and "Selected".

So, now I need to have a page ask the question... "How do you feel about... whatever... Pick all that apply." Then I provide a list... with number or lettered items... The user can select none, any, or all... So I create a view with a series of questions, that have a list of "checkable" items... As I said above, the control works perfectly if it is in a standalone page... If I generate a List of these controls dynamically, Command and CommandParameter suddenly no longer work.

my test implementation looks something like the following... although in this case think something much simpler like a "lottery ticket" number chooser. In this case the ViewModel would have a simple ObservableCollection<string> PrimaryControlList; And, the CommandParamter will call a VM function along with the text of the control in order to track the items the user has selected.

                <Frame x:Name="primaryFrame">
                <FlexLayout x:Name="flexPrimary" BindableLayout.ItemsSource="{Binding PrimaryControlList}" Wrap="Wrap" Direction="Row" JustifyContent="SpaceAround" AlignItems="Start" AlignContent="Start" >
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <local:NumberSelect Text="{Binding .}" Command="Binding DoSomethingWithThis" CommandParameter="{Binding .}"/>
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </FlexLayout>
            </Frame>

Can anyone provide guidance?

1
when any element is included in a DataTemplate, the BindingContext will be the current item from the template's ItemsSource. That means that your Command binding will fail because there is no property "DoSomethingWithThis" on the current element of PrimaryControlList, which is just a string. There are multiple methods to make a binding refer to a different source in your model - refer to the binding docs.Jason
Does my solution work for you? If yes, can you please accept it (click the ☑️ in the upper left corner of this answer ) so that we can help more people with same problem:).Jack Hua

1 Answers

1
votes

The command is in your ViewModel while the current BindingContext of FlexLayout is PrimaryControlList.

Solution:

First, give a name to your ContentPage, let's say it MyPage:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"

             x:Name="MyPage"

             x:Class="App266.MainPage">

Assume your page binds to a ViewModel and your binding of command should be:

<local:NumberSelect Text="{Binding .}" Command="{Binding BindingContext.ButtonCommand, Source={x:Reference MyPage}}" CommandParameter="{Binding .}"/>