0
votes

In my Xamarin Forms project I use the following code to provide mock data to xaml previewer at design time:

C#:

namespace MyApp.Data
{
    public class StaticData
    {
        private static AppMockData mockData;
        public static AppMockData MockData => mockData ?? (mockData = new MockData());

        public class MockData
        {
            public List<MyObj> LstObj { get; set; }
                = new List<MyObj>()
                {
                    new MyObj() { P1 = "V1", P2 = "V2" },
                    new MyObj() { P1 = "V1", P2 = "V2" },
                    new MyObj() { P1 = "V1", P2 = "V2" }
                };

            public MyObj SingleObj { get; set; } = new MyObj() { P1 = "V1", P2 = "V2" };
        }
    }
}

XAML:

<ContentPage xmlns:data="clr-namespace:MyApp.Data"
             BindingContext="{x:Static data:StaticData.MockData}"
             ... >  

<ListView x:Name="MyList" ItemsSource="{Binding LstObj}">
    ...
    <Label Text="{Binding P1}" />
    <Label Text="{Binding P2}" />
    ...
</ListView>

Then, at runtime:

var actualListData = GetDataFromDB(); // obj returned is of type List<MyObj>
MyList.ItemsSource = actualListData;

This is working fine.

I would like to do the same thing with SingleObj, that is, a single object, and not a list. I tried something like:

<ContentPage xmlns:data="clr-namespace:MyApp.Data"
             BindingContext="{x:Static data:StaticData.MockData.SingleObj}"
             ... >

<Label Text="{Binding P1}" />
<Label Text="{Binding P2}" />

and in code behind:

var actualObj = GetDataFromDB(); // obj returned is of type MyObj
this.BindingSource = actualObj;

This works at runtime, but it doesn't at design time: "{x:Static data:StaticData.MockData.SingleObj}" is not recognized as a valid expression.

The only way I could make it work both at design time and at runtime is:

<ContentPage xmlns:data="clr-namespace:MyApp.Data"
             BindingContext="{x:Static data:StaticData.MockData}"
             ... >

<StackLayout x:Name="MyStackLayout" BindingContext="{Binding SingleObj}">
    <Label Text="{Binding P1}" />
    <Label Text="{Binding P2}" />
</StackLayout>

and:

var actualObj = GetDataFromDB(); // obj returned is of type MyObj
MyStackLayout.BindingContext = actualObj;    

This way I have a StackLayout (used only for binding purposes) whose BindingContext is a property of MockData at design time, and the actual object at runtime.

I wonder if there is a syntax to specify SingleObj directly in ContentPage BindingContext, thus avoiding to put everything in a container layout.

1
Hi , have you solved it ? The ViewModel will be different effects between design time and runtime .Typically, the runtime performance is better .docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/…Junior Jiang

1 Answers

0
votes

add SingleObj to your binding path expression

<ContentPage xmlns:data="clr-namespace:MyApp.Data"
             BindingContext="{x:Static data:StaticData.ViewModel}"
             ... >

<StackLayout>
    <Label Text="{Binding SingleObj.P1}" />
    <Label Text="{Binding SingleObj.P2}" />
</StackLayout>