ConfusedDeveloper
ConfusedDeveloper

Reputation: 7001

Load dynamic controls using Xamarin MVVM

I am developing an application in Xamarin Forms using MVVM where I have this JSON:

[{
    type: 'text',
    title: 'Name'
    value: 'John',
    width: 50
},
{
    type: 'radio'
    Source: ['Male', 'Female']
    value: 'Male',
    width: 100
},
{
    type: 'checkbox'
    title: 'Married'
    value: false,
    width: 100
}]

Based on this JSON, I want to load controls (TextBox, RadioButton, and CheckBox in this example). I tried to find a solution but I couldn't get succeed.

This is a dynamic JSON retrieved from the database. It could be with different controls also. Is there a way to implement this?

Upvotes: 0

Views: 2065

Answers (2)

Nikhileshwar
Nikhileshwar

Reputation: 1684

Hi @confusedDeveloper,

Jason's answer works well while not considering MVVM pattern. However with MVVM it needs a little more code.

Dynamically changing of a view's content can be achieved in MVVM pattern by simply creating a view component deriving from ContentView with a BindableProperty and handling the changes to the bindable property.

Here I have created a View component ChangingView

  1. In Xaml of the View Component assign a content view to the ComponentView

    <ContentView.Content>
    <ContentView Grid.Row="1" x:Name="mainView">
            <ContentView.Content>
                <Label BackgroundColor="Gray" Text="Placeholder"/>
            </ContentView.Content>
    </ContentView>
    </ContentView.Content>
    
  2. In the Xaml.cs of the ComponentView create BindableProperty and handle its changes.

    // Fetch the required parameter from JSON and bind it to this property
    public string ViewType
    {
        get { return (string)GetValue(ViewTypeProperty); }
        set
        {
            SetValue(ViewTypeProperty, value);
        }
    }
    
    //Notice the OnViewChanged method subscription
    public static readonly BindableProperty ViewTypeProperty = BindableProperty.Create("ViewType", typeof(string), typeof(ChangingView), "placeholder", BindingMode.Default, null, OnViewChanged);
    

This static method is call a method similar to code in @Jason's answer

private static void OnViewChanged(BindableObject bindable, object oldvalue, object newValue)
    {
        var viewControl = (bindable as ChangingView);
        if (viewControl != null)
        {
            viewControl.ChangeView((string)newValue);
        }
    }


private void ChangeView(string viewType)
    {
        if(viewType == "Button")
        {
            this.mainView.Content = new Button()
            {
                BackgroundColor= Color.Red,
                Text = "Button"
            };
        }
        else if(viewType == "Label")
        {
            this.mainView.Content = new Label()
            {
                BackgroundColor= Color.Green,
                Text = "Label"
            };
        }
    }
  1. Finally use the component in Xaml of the Page where you require this ChangingView, The DisplayControl is the string derived from the required JSON parameter (Done in ViewModel, I leave this up to you).

    <component:ChangingView ViewType="{Binding DisplayControl}"/>
    

Hope it fits your scenario. Comment if further information is required.

Thanks,

Upvotes: 2

Jason
Jason

Reputation: 89082

there are lots of ways to tackle this - one approach would be to do something like this

foreach(var c in json)
{
  switch(c.type) {
    case "text":
      var c = new Entry() { ... };
      myLayout.Children.Add(c);
      break;
    case "checkbox":
      var c = new Checkbox() { ... };
      myLayout.Children.Add(c);
      break; 
    case ...
  }
}

Upvotes: 1

Related Questions