Reputation: 7001
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
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
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>
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"
};
}
}
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
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