0

I developed a simple two-lines custom control to host a Name-Value pair and display it with reusable logicl. I could set up the link between the two properties and the XAML using two BindableProperty that set the value of the two labels.

This is my custom control XAML:

<?xml version="1.0" encoding="UTF-8"?>
<StackLayout
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="SystemOne.ui.GenericItem"
    Orientation="Vertical">
    <Label x:Name="TitleLabel" />
    <Label x:Name="ContentLabel"/>
</StackLayout>

This is one of the Properties & related BindableProperty in the code behind:

public string TextContent { get; set; }
public static readonly BindableProperty TextContentProperty = BindableProperty.Create(
    propertyName: "TextContent",
    returnType: typeof(string),
    declaringType: typeof(GenericItem),
    defaultValue: "",
    propertyChanged: TextContentPropertyChanged);
private static void TextContentPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        GenericItem GenericItem = (GenericItem)bindable;
        GenericItem.ContentLabel.Text = newValue.ToString();
    }

This allows to use the GenericItem custom control in any Page in this way (definig proper namespace):

<ui:GenericItem x:Name="MyGenItem" TextContent="{Binding MyViewModel.MyContentText}" />

The GenericItem custom-control takes the value for the its Lable 'ContentLabel' from the binding defined for the TextContent property.

Now I woluld like to develope something that allows a usage with this pseudo-XAML:

<ui:GenericItem x:Name="MyGenItem" TextContent="{Binding MyViewModel.MyContentText}" Clicked="{Binding MyViewModel.SomeProperty}"/>

or even not binded:

<ui:GenericItem x:Name="MyGenItem" TextContent="{Binding MyViewModel.MyContentText}" Clicked="MyGenericItem_Tapped"/>

where 'MyGenericItem_Tapped' is an Event handler method defined in code-behind of the page the is creating the 'MyGenItem' instnce of the GeneriItem control.

I could not find a way!

mcfoi
  • 74
  • 7

1 Answers1

0

I use the ContentView to make the custom control like below:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="App17.GenericItem">
<ContentView.Content>
    <StackLayout Orientation="Vertical">
        <Label x:Name="TitleLabel"  />
        <Label x:Name="ContentLabel"  />
    </StackLayout>
</ContentView.Content>
 </ContentView>

And then use the GestureRecognizers directly instead of touch-event listener which using Bindable Property.

   <ui:GenericItem x:Name="MyGenItem" TextContent="{Binding MyContentText}">
            <ui:GenericItem.GestureRecognizers>
                <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
            </ui:GenericItem.GestureRecognizers>
        </ui:GenericItem>

If you want to use the binding for the GestureRecognizers, you could use ICommand.

Xaml:

  <ui:GenericItem x:Name="MyGenItem" TextContent="{Binding MyContentText}">
            <ui:GenericItem.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding TapGestureRecognizer_Command}"></TapGestureRecognizer> 
            </ui:GenericItem.GestureRecognizers>
        </ui:GenericItem>

Code behind:

public partial class Page14 : ContentPage
{
    public Page14()
    {
        InitializeComponent();
        this.BindingContext = new MyViewModel();
    }       
}
public class MyViewModel
{
    public Command TapGestureRecognizer_Command { get; set; }
    public string MyContentText { get; set; }
    public MyViewModel()
    {
        MyContentText = "Hello";
        TapGestureRecognizer_Command = new Command(TappedCommand);
    }

    private void TappedCommand(object obj)
    {
        Console.WriteLine("TappedCommand");
    }
}
Wendy Zang - MSFT
  • 10,509
  • 1
  • 7
  • 17