How to create a bindable view property inside a custom control

GaetanFGaetanF USMember ✭✭✭

Hi guys,

I am trying to create a view that can contain another view but for unknown reason, I get weird behaviours!
This is what I have so far:

CustomView.xaml:

<?xml version="1.0" encoding="UTF-8"?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
      x:Class="AppTest.CustomView"
      HorizontalOptions="FillAndExpand"
      VerticalOptions="FillAndExpand"
      BackgroundColor="Aqua">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*" />
        <RowDefinition Height="1*" />
        <RowDefinition Height="1*" />
    </Grid.RowDefinitions>

    <Label Grid.Column="0"
           Grid.Row="0"
           Grid.ColumnSpan="3"
           BackgroundColor="Chartreuse"
           Text="fdtyu7osrtjsrdytj"/>
    <ContentView x:Name="ViewContent"
                 Grid.Column="1"
                 Grid.Row="1"
                 HorizontalOptions="FillAndExpand"
                 VerticalOptions="FillAndExpand"
                 BackgroundColor="Coral"/>
</Grid>

CustomView.xaml.cs:

using System.Diagnostics;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace AppTest
{
    [ContentProperty(nameof(Content))]
    [XamlCompilation(XamlCompilationOptions.Skip)]
    public partial class CustomView : Grid
    {
        public CustomView()
        {
            Debug.WriteLine(nameof(InitializeComponent) + " started!");
            InitializeComponent();
            Debug.WriteLine(nameof(InitializeComponent) + " ended");
        }

        #region Content (Bindable Xamarin.Forms.View)

        /// <summary>
        /// Manages the binding of the <see cref="Content"/> property
        /// </summary>
        public static readonly BindableProperty ContentProperty
            = BindableProperty.Create(propertyName: nameof(Content)
                                    , returnType: typeof(Xamarin.Forms.View)
                                    , declaringType: typeof(CustomView)
                                    , defaultBindingMode: BindingMode.OneWay
                                    , propertyChanged: Content_PropertyChanged
                                    );

        public Xamarin.Forms.View Content { get => (Xamarin.Forms.View)GetValue(ContentProperty); set => SetValue(ContentProperty, value); }

        private static void Content_PropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (CustomView)bindable;
            var value = (View)newValue;

            if (control.ViewContent == null) Debug.WriteLine("ViewContent null!");
            if (ReferenceEquals(newValue, control)) Debug.WriteLine("New value is myself!!!!");
            if (newValue is Label label)
            {
                Debug.WriteLine("Added label with text: " + label.Text);
                if (label.Text.Equals("abc")) control.ViewContent.Content = (View)newValue;
            }
        }

        #endregion Content (Bindable Xamarin.Forms.View)
    }
}

CustomPage.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="AppTest.CustomPage"
             xmlns:local="clr-namespace:AppTest">
    <local:CustomView x:Name="view">
        <Label Text="abc"/>
    </local:CustomView>
</ContentPage>

That's it. The app just launches a CustomPage.
I have a bunch of weird behavior when launching the windows emulator API 19.
Depending on the XamlCompilationOptions, I get different behaviours but always an Aqua coloured page with no labels as a final result :

  • For Skip:

    [0:] InitializeComponent started!
    [0:] ViewContent null!
    [0:] Added label with text: fdtyu7osrtjsrdytj
    [0:] ViewContent null!
    [0:] InitializeComponent ended
    [0:] Added label with text: abc

  • For Compile:

    [0:] InitializeComponent started!
    [0:] Added label with text: fdtyu7osrtjsrdytj
    [0:] InitializeComponent ended
    [0:] Added label with text: abc

I can't get my mind around it! It should basically say InitializeComponent started=>ended then Added label with text: abc.
The project settings are: .Net Standard 1.4 core library, Xamarin.Forms nuget v2.5.0.280555, Xamarin.Android.Support nuget v25.4.0.2, Windows emulator for android.
Can anyone reproduce this behaviour and explain this to me or have an idea, please?

Cheers,

G.

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Tutorial on re-usable controls with bindable properties
    https://redpillxamarin.com/2017/01/28/206-reusable-controls/

  • JohnHardmanJohnHardman GBUniversity mod

    @ClintStLaurent - Just in case you're not seeing it, Chrome is reporting the following when I click on that link:

    Your connection is not private
    Attackers might be trying to steal your information from redpillxamarin.com (for example, passwords, messages, or credit cards). Learn more
    NET::ERR_CERT_COMMON_NAME_INVALID

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @JohnHardman

    Huh? Thanks. I turned off the GeoIPblock temporarily because it was blocking me when trying to admin from work over VPN. I wouldn't think that should affect it.. but.. eh... who knows when it comes to Wordpress? I'll dig into it over the weekend.

  • GaetanFGaetanF USMember ✭✭✭
    edited March 2018

    Thanks @ClintStLaurent for the tutorial link.
    Although I found it interesting, I could not find anything that could solve my issue.
    I tried to trim the CustomView control by removing ContentView control at the root because it's just a layout class with a content property and I was thinking a Grid could do the job as good as a ContentView, am I right? Still, it does not explain the weird behaviour...

  • GaetanFGaetanF USMember ✭✭✭

    Bump!

  • ghasanghasan Member ✭✭

    @ClintStLaurent said:
    Tutorial on re-usable controls with bindable properties

    Thank you for the tutorial. I have been using custom controls for sometime now, but I was in doubt of referencing 'this' for each binding inside the same view. You tutorial assured me. Thanks.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @ghasan Cheers mate! Glad it helped.

Sign In or Register to comment.