Bug 56333 - PropertyChanged of custom Bindable property of a Custom view is called before InitializeComponent is called
Summary: PropertyChanged of custom Bindable property of a Custom view is called before...
Status: CONFIRMED
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: 2.3.4
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Stephane Delcroix
URL:
Depends on:
Blocks:
 
Reported: 2017-05-13 09:12 UTC by Gagik Kyurkchyan
Modified: 2017-06-19 19:18 UTC (History)
5 users (show)

Tags: xaml styles ac
Is this bug a regression?: Yes
Last known good build: 2.3.3.193


Attachments
Sample project to reproduce the issue (178.65 KB, application/x-rar)
2017-05-16 07:11 UTC, Gagik Kyurkchyan
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 56333 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description Gagik Kyurkchyan 2017-05-13 09:12:25 UTC
I have multiple custom views with custom bindable properties in my project. Before Xamarin 2.3.4 everything was working Ok. After updating to 2.3.4 my custom views stopped working. Take a look here

 public partial class RightIconButton
    {
        public RightIconButton()
        {
            InitializeComponent();
        }

        public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text),
                                                                                       typeof(string),
                                                                                       typeof(RightIconButton),
                                                                                       Strings.AddNew,
                                                                                       propertyChanged:OnTextChanged);

        public string Text
        {
            get { return (string) GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        private static void OnTextChanged(BindableObject bindable, object oldvalue, object newvalue)
        {
            var button = (RightIconButton) bindable;
            button.TitleLabel.Text = Text;
        }
}

My custom view has a backing xaml. So the TitleLabel is inside the xaml. The issue is when I use this view and set the Text property, the OnTextChanged method is getting called even before InitializeComponent is called. Thus TitleLabel is never initiated and I get a null reference exception. Same thing happens for all other views. This has been a breaking change on Xamarin.Forms 2.3.4.
Comment 1 Gagik Kyurkchyan 2017-05-16 07:11:24 UTC
Created attachment 22186 [details]
Sample project to reproduce the issue

UPDATE

I found what is the exact issue and have attached sample project through which you can 100% reproduce the issue. The issue is that if you have custom view with custom bindable property let's say It's Color, and you set default style in the App.xaml, the style is applied event before InitializeComponent is called.
Comment 2 Jimmy [MSFT] 2017-05-19 21:52:03 UTC
Thank you for filing this report! I am able to reproduce the crash using the attached repro project.

As mentioned in comment 1, the issue does appear to be that in 2.3.4 the implicit style is applied _before_ InitializeComponent(), so none of the view's children are instantiated at that point. This is different behavior than in 2.3.3 and therefore a possible regression.


### Version Test
2.3.6.102   BAD
2.3.5-pre3  BAD
2.3.4.247   BAD
2.3.3.193   GOOD
Comment 3 Jon Scalet 2017-05-19 22:46:22 UTC
+1 

I'm having the same issue. Any suggestions from the XForms team on how we can work around this? As Gagik mentioned, we too, have reusable controls with properties set globally. 

It's a pretty big pain for us.

Thanks.
Comment 4 Stephane Delcroix 2017-05-23 09:46:51 UTC
> Any suggestions from the XForms team on how we can work around this?

use bindings from the Xaml to the BP

instead of doing this in code-behind:

    button.TitleLabel.Text = Text;

do this in the Xaml

    <Button Text="{Binding Text, Source={x:Reference rightIconButton}}" />

this will work if you set a x:Name="rightIconButton" on the top level element of your Xaml file:

    <RightIconButton ... x:Name="rightIconButton" >
Comment 5 Ryan 2017-06-08 17:46:53 UTC
Stephane, I don't quite understand this solution

What source am I referencing that has the Text property to bind to?

I have a page with an instance of my custom control that has bindable properties bound from the view model and from static references ( text, colors, commands, etc.) and I don't quite understand how I can reference those bindings in the custom control xaml file. 

this is my custom control xaml. It uses property change events to set its bindable properties:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="CiiCommon.Controls.SvgButton"
		xmlns:svg="clr-namespace:XamSvg.XamForms;assembly=XamSvg.XamForms">
  <ContentView.Content>
    <StackLayout x:Name="SVGStackLayout">
      <Frame Padding="0" HasShadow="false" HorizontalOptions="Fill" VerticalOptions="Fill" x:Name="Frame">
        <StackLayout Orientation="Horizontal" Padding="10,5,10,5" HorizontalOptions="FillAndExpand" x:Name="Layout">
          <svg:SvgImage Svg="res:Images.icon_logEntry.svg" HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="50" x:Name="SvgImage" Clicked="SvgImage_Clicked" >

          </svg:SvgImage>
          <Label TextColor="White" VerticalOptions="Center" HorizontalOptions="CenterAndExpand" FontSize="14" x:Name="Label"/>
          <StackLayout.GestureRecognizers>
            <TapGestureRecognizer x:Name="TapGesture"
                CommandParameter="{Binding .}" Tapped="SvgImage_Clicked"/>
          </StackLayout.GestureRecognizers>
        </StackLayout>
      </Frame>
    </StackLayout>
  </ContentView.Content>
</ContentView>

Upgrading Xamarin on our build machine has forced us to upgrade xamarin.forms to 2.3.4 and this issue is breaking all of our pages :((