1

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"
  xmlns:local="clr-namespace:mvvmtest"
  x:Class="mvvmtest.mvvmtestPage"
  BindingContext="{Binding TestViewModel, Source={StaticResource Locator}}">

<Label
    Text="Welcome to Xamarin Forms!"
    VerticalOptions="Center"
    HorizontalOptions="Center" />
</ContentPage>

App:

public App()
{
    InitializeComponent();

    var locator = new ViewLocator();
    Current.Resources.Add("Locator", locator);

    MainPage = new mvvmtestPage();
}

ViewLocator:

public class ViewLocator
{
    public TestViewModel TestViewModel
    {
        get { return new TestViewModel(); }
    }
}

TestViewModel:

public class TestViewModel
{

    public static int InstancesNum = 0;

    public TestViewModel()
    {
        Debug.WriteLine(++InstancesNum);
    }
}

Wondering why the TesViewModel constructor is called twice.

Call Stack:

mvvmtest.ViewLocator.get_TestViewModel() in /Users/xxx/Projects/mvvmtest/mvvmtest/ViewLocator.cs:8
System.Reflection.MonoMethod.InternalInvoke() in 
Xamarin.Forms.BindingExpression.BindingExpressionPart.TryGetValue(mvvmtest.ViewLocator source, mvvmtest.ViewLocator value) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindingExpression.cs:565
Xamarin.Forms.BindingExpression.ApplyCore(mvvmtest.ViewLocator sourceObject, mvvmtest.mvvmtestPage target, Xamarin.Forms.BindableProperty property, bool fromTarget) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindingExpression.cs:160
Xamarin.Forms.BindingExpression.Apply(mvvmtest.ViewLocator sourceObject, mvvmtest.mvvmtestPage target, Xamarin.Forms.BindableProperty property) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindingExpression.cs:76
Xamarin.Forms.Binding.Apply(object newContext, mvvmtest.mvvmtestPage bindObj, Xamarin.Forms.BindableProperty targetProperty) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Binding.cs:122
Xamarin.Forms.BindableObject.SetBinding(Xamarin.Forms.BindableProperty targetProperty, Xamarin.Forms.Binding binding, bool fromStyle) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindableObject.cs:281
Xamarin.Forms.BindableObject.SetBinding(Xamarin.Forms.BindableProperty targetProperty, Xamarin.Forms.Binding binding) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindableObject.cs:78
Xamarin.Forms.Xaml.ApplyPropertiesVisitor.TrySetBinding(mvvmtest.mvvmtestPage element, Xamarin.Forms.BindableProperty property, string localName, Xamarin.Forms.Binding value, Xamarin.Forms.Xaml.ElementNode lineInfo, System.Exception exception) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Xaml\ApplyPropertiesVisitor.cs:371
Xamarin.Forms.Xaml.ApplyPropertiesVisitor.SetPropertyValue(mvvmtest.mvvmtestPage xamlelement, Xamarin.Forms.Xaml.XmlName propertyName, Xamarin.Forms.Binding value, mvvmtest.mvvmtestPage rootElement, Xamarin.Forms.Xaml.ElementNode node, Xamarin.Forms.Xaml.HydratationContext context, Xamarin.Forms.Xaml.ElementNode lineInfo) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Xaml\ApplyPropertiesVisitor.cs:290
Xamarin.Forms.Xaml.ApplyPropertiesVisitor.Visit(Xamarin.Forms.Xaml.ElementNode node, Xamarin.Forms.Xaml.XamlLoader.RuntimeRootNode parentNode) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Xaml\ApplyPropertiesVisitor.cs:119
Xamarin.Forms.Xaml.ElementNode.Accept(Xamarin.Forms.Xaml.ApplyPropertiesVisitor visitor, Xamarin.Forms.Xaml.XamlLoader.RuntimeRootNode parentNode) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Xaml\XamlNode.cs:176
Xamarin.Forms.Xaml.RootNode.Accept(Xamarin.Forms.Xaml.ApplyPropertiesVisitor visitor, Xamarin.Forms.Xaml.INode parentNode) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Xaml\XamlNode.cs:224
Xamarin.Forms.Xaml.XamlLoader.Visit(Xamarin.Forms.Xaml.XamlLoader.RuntimeRootNode rootnode, Xamarin.Forms.Xaml.HydratationContext visitorContext) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Xaml\XamlLoader.cs:125
Xamarin.Forms.Xaml.XamlLoader.Load(mvvmtest.mvvmtestPage view, string xaml) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Xaml\XamlLoader.cs:76
Xamarin.Forms.Xaml.XamlLoader.Load(mvvmtest.mvvmtestPage view, System.RuntimeType callingType) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Xaml\XamlLoader.cs:56
Xamarin.Forms.Xaml.Extensions.LoadFromXaml<mvvmtest.mvvmtestPage>(mvvmtest.mvvmtestPage view, System.RuntimeType callingType) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Xaml\ViewExtensions.cs:36
mvvmtest.mvvmtestPage.InitializeComponent() in /Users/xxx/Projects/mvvmtest/mvvmtest/obj/Debug/mvvmtest.mvvmtestPage.xaml.g.cs:21
mvvmtest.mvvmtestPage..ctor() in /Users/xxx/Projects/mvvmtest/mvvmtest/mvvmtestPage.xaml.cs:10
mvvmtest.App..ctor() in /Users/xxx/Projects/mvvmtest/mvvmtest/App.xaml.cs:14
mvvmtest.iOS.AppDelegate.FinishedLaunching(UIKit.UIApplication app, Foundation.NSDictionary options) in /Users/xxx/Projects/mvvmtest/iOS/AppDelegate.cs:17
UIKit.UIApplication.UIApplicationMain() in 
UIKit.UIApplication.Main(string[] args, System.IntPtr principal, System.IntPtr delegate) in /Users/builder/data/lanes/3985/62816dd6/source/xamarin-macios/src/UIKit/UIApplication.cs:79
UIKit.UIApplication.Main(string[] args, string principalClassName, string delegateClassName) in /Users/builder/data/lanes/3985/62816dd6/source/xamarin-macios/src/UIKit/UIApplication.cs:63
mvvmtest.iOS.Application.Main(string[] args) in /Users/xxx/Projects/mvvmtest/iOS/Main.cs:17

mvvmtest.ViewLocator.get_TestViewModel() in /Users/xxx/Projects/mvvmtest/mvvmtest/ViewLocator.cs:8
System.Reflection.MonoMethod.InternalInvoke() in 
Xamarin.Forms.BindingExpression.BindingExpressionPart.TryGetValue(mvvmtest.ViewLocator source, mvvmtest.ViewLocator value) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindingExpression.cs:565
Xamarin.Forms.BindingExpression.ApplyCore(mvvmtest.ViewLocator sourceObject, mvvmtest.mvvmtestPage target, Xamarin.Forms.BindableProperty property, bool fromTarget) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindingExpression.cs:160
Xamarin.Forms.BindingExpression.Apply(mvvmtest.ViewLocator sourceObject, mvvmtest.mvvmtestPage target, Xamarin.Forms.BindableProperty property) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindingExpression.cs:76
Xamarin.Forms.Binding.Apply(mvvmtest.TestViewModel newContext, mvvmtest.mvvmtestPage bindObj, Xamarin.Forms.BindableProperty targetProperty) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Binding.cs:122
Xamarin.Forms.BindableObject.ApplyBindings(mvvmtest.TestViewModel oldContext, bool skipBindingContext) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindableObject.cs:408
Xamarin.Forms.BindableObject.ApplyBindings(mvvmtest.TestViewModel oldContext) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindableObject.cs:123
Xamarin.Forms.BindableObject.SetInheritedBindingContext(mvvmtest.mvvmtestPage bindable, object value) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindableObject.cs:117
Xamarin.Forms.Element.SetChildInheritedBindingContext(mvvmtest.mvvmtestPage child, object context) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Element.cs:482
Xamarin.Forms.Element.set_Parent(mvvmtest.App value) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Element.cs:196
Xamarin.Forms.Application.set_MainPage(mvvmtest.mvvmtestPage value) in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Application.cs:86
mvvmtest.App..ctor() in /Users/xxx/Projects/mvvmtest/mvvmtest/App.xaml.cs:14
mvvmtest.iOS.AppDelegate.FinishedLaunching(UIKit.UIApplication app, Foundation.NSDictionary options) in /Users/xxx/Projects/mvvmtest/iOS/AppDelegate.cs:17
UIKit.UIApplication.UIApplicationMain() in 
UIKit.UIApplication.Main(string[] args, System.IntPtr principal, System.IntPtr delegate) in /Users/builder/data/lanes/3985/62816dd6/source/xamarin-macios/src/UIKit/UIApplication.cs:79
UIKit.UIApplication.Main(string[] args, string principalClassName, string delegateClassName) in /Users/builder/data/lanes/3985/62816dd6/source/xamarin-macios/src/UIKit/UIApplication.cs:63
mvvmtest.iOS.Application.Main(string[] args) in /Users/xxx/Projects/mvvmtest/iOS/Main.cs:17

Found a reported bugs:

https://bugzilla.xamarin.com/show_bug.cgi?id=27299
https://bugzilla.xamarin.com/show_bug.cgi?id=45557
Most probably it's still not fixed.

Workaround:

<ContentPage.BindingContext>
    <local:TestViewModel />
</ContentPage.BindingContext>
EvZ
  • 11,889
  • 4
  • 38
  • 76
  • 1
    every time it's getter is called it will return a new instance - is that what you intended? – Jason Mar 13 '17 at 18:49
  • The getter should be called only once but it's getting called twice. – EvZ Mar 13 '17 at 18:51
  • my best guess is that it's getting called once when the XAML is parsed, and again when the Binding is evaluated. You might try enabling XAML compilation to see if that makes any difference? You might try filing a bug with Xamarin, but it may also be working the way they intended. – Jason Mar 13 '17 at 19:01
  • Ah, according to the bug notes it should have been fixed long ago. I'd reopen the bug and attach a new test case. – Jason Mar 13 '17 at 19:02
  • https://github.com/xamarin/Xamarin.Forms/pull/470 weird, should be fixed already. Could you please share a link to the reported bug? – EvZ Mar 13 '17 at 19:04
  • I was referring to 27299, which says it was fixed in 2015. Possibly it's a regression? – Jason Mar 13 '17 at 20:08
  • It is not fixed.Using 2.3.4.231 still happens. – Roland May 03 '17 at 16:40
  • Same story in 2.3.4.270, bug is still there. – EvZ Aug 31 '17 at 10:50

0 Answers0