Working with DataForm in Xamarin DataForm (SfDataForm)

Auto-generating DataFormItems for the data field

By default, the DataFormItems will be generated based on the property type. For example, the DataFormNumericItem will be created for the int type property. 

The DataFormItem generation depends on the type and attribute defined for the property.
The following tables lists the several types of DataFormItem and its constraints for auto generation:

Generated DataFormItem Type Editor Data Type / Attribute

DataFormTextItem

Text Default DataFormItem generated for the String type and the properties with [DataType(DataType.Text)], [DataType(DataType.MultilineText)] and [DataType(DataType.Password)] attributes.

DataFormNumericItem

Numeric Generated for Int, Double, Float, Decimal, Long types and also its nullable property with [DataType(DataType.Currency)] and [DataType("Percent")] attributes.

DataFormDateItem

Date Generated for DateTime type and properties with [DataType(DataType.Date)] and [DataType(DataType.DateTime)] attributes.

DataFormTimeItem

Time Generated for the property with [DataType(DataType.Time)] attribute.

DataFormPickerItem

Picker Generated for Enum type property and the property with [EnumDataTypeAttribute] attribute.

DataFormDropDownItem

DropDown Generated for Enum type property and the property with [EnumDataTypeAttribute] attribute.

DataFormAutoCompleteItem

AutoComplete Generated for Enum type property and the property with [EnumDataTypeAttribute] attribute.

DataFormMaskedEditTextItem

MaskedEditText Generated for the PhoneNumber type property. [DataType(DataType.PhoneNumber)]

DataFormItem

CheckBox Bool type

You can customize the property settings or cancel the generation of DataFormItem by handling the AutoGeneratingDataFormItem event.

Customize auto generated fields

You can customize or cancel the generated DataFormItem by handling the AutoGeneratingDataFormItem event. This event occurs when the field is auto-generated for public and non-static property of the data object.

<?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:GettingStarted"
             xmlns:dataForm="clr-namespace:Syncfusion.XForms.DataForm;assembly=Syncfusion.SfDataForm.XForms"
             x:Class="GettingStarted.MainPage">
    <ContentPage.Content>
        <dataForm:SfDataForm x:Name="dataForm" AutoGeneratingDataFormItem="DataForm_AutoGeneratingDataFormItem"/>
    </ContentPage.Content>
</ContentPage>
dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;

private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
{

}

AutoGeneratingDataFormItemEventArgs provides the information about the auto-generated.  AutoGeneratingDataFormItemEventArgs.DataFormItem  property returns the newly created DataFormItem.

Cancel DataFormItem generation of the data field

You can cancel the specific DataFormItem adding to the data form by handling the AutoGeneratingDataFormItem event or by defining display attribute to avoid the particular data field being displayed.

Using attributes

You can set AutoGenerateField to false for canceling the DataFormItem generation.

private int id;
[Display(AutoGenerateField = false)]
public int ID
{
    get
    {
        return id;
    }
    set
    {
        id = value;
        RaisePropertyChanged("ID");
    }
}

Using event

In the following code, the DataFormItem generation for the MiddleName property is canceled by setting the Cancel property to true.

dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;

private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
{
    if (e.DataFormItem.Name == "MiddleName")
        e.Cancel = true;
}

Changing editor type

You can change the editor of the DataFormItem in the AutoGeneratingDataFormItem event.

In the following code, the editor is changed for IsAvailable field from Bool to Switch.

dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;

private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
{
    if (e.DataFormItem.Name == "IsAvailable")
        e.DataFormItem.Editor = "Switch";
}

Changing property settings

You can change the property of DataFormItem in the AutoGeneratingDataFormItem event.

Here, Salary data field is restricted from being edited in the data form.

dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;

private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
{
    if (e.DataFormItem != null)
    {
        if (e.DataFormItem.Name == "Salary")
            e.DataFormItem.IsReadOnly = true;
    }
}

Changing DataFormItem visibility

You can change the DataFormItem visibility by using the IsVisible property in the DataFormItem.

Here, Salary data field will be hidden.

dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;

private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
{
    if (e.DataFormItem != null)
    {
        if (e.DataFormItem.Name == "Salary")
            e.DataFormItem.IsVisible = false;
    }
}

Changing DataFormItem FontSize

Using the EditorFontSize, LabelFontSize, and ValidationLabelFontSize properties from DataFormItem, you can define the font size of the Editor, Label, and ValidationLabel. Changing the font size will be handled in the AutoGeneratingDataFormItem event.

You can define the font size as described as follows.

  • Set the value to font size directly or use the named font sizes such as Small, Medium, and Large.
dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;
private void DataForm_AutoGeneratingDataFormItem(object sender,AutoGeneratingDataFormItemEventArgs e)
{
   if (e.DataFormItem != null)
     {
          // Setting Fontsize using NamedSize.                
          e.DataFormItem.EditorFontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label));
          e.DataFormItem.LabelFontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label));
          e.DataFormItem.ValidationLabelFontSize = Device.GetNamedSize(NamedSize.Micro, typeof(Label));
          // Setting value to FontSize directly.                
          e.DataFormItem.EditorFontSize = 8;
          e.DataFormItem.LabelFontSize = 8;
          e.DataFormItem.ValidationLabelFontSize = 8; 
     }
}

Setting watermark

You can display the watermark in the editor by defining the display attribute or using theAutoGeneratingDataFormItem event.

Using attribute

You can show the watermark in the editor by setting the Prompt in display attribute.

private string middleName;
[Display(Prompt = "Enter middle name")]
public string MiddleName
{
    get { return this.middleName; }
    set
    {
        this.middleName = value;
    }
}

Using event

You can show the watermark in the editor by using the PlaceHolderText property in DataFormItem.

dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;

private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
{
    if (e.DataFormItem != null)
    {
        if (e.DataFormItem.Name == "Description")
            e.DataFormItem.PlaceHolderText = "Enter description";
    }
}

Changing DataFormItem

You can change the created DataFormItem and assign new DataFormItem in the AutoGeneratingDataFormItem event.

Here, DataFormTextItem with number keyboard is loaded for numeric value instead of DataFormNumericItem.

  • c#
  • dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;
    
    private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
    {
        if (e.DataFormItem != null)
        {
           if (e.DataFormItem.Name == "ID")
              e.DataFormItem = new DataFormTextItem() { Name = "ID", Editor = "Text", KeyBoard = Keyboard.Numeric };
        }
    }

    Adding or removing the data field displayed in the dataForm at runtime

    If you want to remove or add data fields item at runtime, you can use the RefreshLayout method which auto-generates the DataFormItem where you can skip certain item from display. By default, it will generate the canceled items initially. If you want to regenerate all the items, you should pass argument as true.

    In the following code snippet, items are auto generated based on refreshLayout flag where you can change flag at runtime and call RefreshLayout method to add or remove items being displayed in the data form at runtime.

    <?xml version="1.0" encoding="utf-8" ?>
    <?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:GettingStarted"
                 xmlns:dataForm ="clr-namespace:Syncfusion.XForms.DataForm;assembly=Syncfusion.SfDataForm.XForms"
                 x:Class="GettingStarted.MainPage">
        <ContentPage.Content>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <dataForm:SfDataForm Grid.Row="0" x:Name="dataForm" AutoGeneratingDataFormItem="DataForm_AutoGeneratingDataFormItem"/>
                <Button x:Name="Commit" Grid.Row="1" WidthRequest="100" HeightRequest="50" Text="MORE FIELDS" Clicked="Button_Clicked"/>
            </Grid>
        </ContentPage.Content>
    </ContentPage>
    dataForm.DataObject = new ContactsInfo();
    
    private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
    {
        if (e.DataFormItem != null)
        {
            if (!refreshLayout)
            {
                if (e.DataFormItem.Name.Equals("MiddleName") || e.DataFormItem.Name.Equals("LastName"))
                    e.Cancel = true;
            }
            else
            {
                if (e.DataFormItem.Name == "GroupName")
                    e.Cancel = true;
            }
        }
    }

    Initial rendering of data form items in Xamarin.Forms DataForm

    If you want to generate the MiddleName and LastName fields at runtime, you should set refreshLayout flag to true and call the RefreshLayout method which triggers AutoGeneratingDataFormItem event again and generates the items based on refreshLayout flag.

    private void Button_Click(object sender, System.EventArgs e)
    {
        refreshLayout = true;
        dataForm.RefreshLayout();
    }

    Here, the MiddleName and LastName fields are generated at runtime after clicking the more field button.

    Adding data form fields at run time in Xamarin.Forms DataForm

    TheGroupNamefield is displayed initially in the data form. If you want to remove it at runtime, you should set refreshLayout flag to true and pass the argument as true inRefreshLayout method. It triggers AutoGeneratingDataFormItem event for all the fields where you can cancel `GroupName’ field item generation.

    private void Button_Click(object sender, System.EventArgs e)
    {
        refreshLayout = true;
        dataForm.RefreshLayout(true);
    }

    Here, the GroupName field is removed at runtime.

    Removing data form fields at run time in Xamarin.Forms DataForm

    You can download the sample from here.

    DataFormItemManager

    The DataFormItemManager creates DataFormItems collection and handles value reflection and validation. It also overrides to handle the get and set property values from and to the data object.

    Manually generate DataFormItems for DataObject

    By default, DataFormItems will be generated based on DataObject. If you need to generate DataFormItems manually, override the DataFormItemManager class and set it to SfDataForm.ItemManager.

    To create DataFormItems, override the GenerateDataFormItems method.

  • c#
  • // dataform item creating by setting DataObject.
    dataForm.DataObject = new ContactsInfo();
    dataForm.ItemManager = new DataFormItemManagerExt(dataForm);
    
    public class DataFormItemManagerExt : DataFormItemManager
    {       
        SfDataForm sfDataForm;
        public DataFormItemManagerExt(SfDataForm dataForm) : base(dataForm)
        {
            sfDataForm = dataForm;
        }
        protected override List<DataFormItemBase> GenerateDataFormItems(PropertyInfoCollection itemProperties, List<DataFormItemBase> dataFormItems)
        {
            var items = new List<DataFormItemBase>();
            foreach (var propertyInfo in itemProperties)
            {
                DataFormItem dataFormItem;
    		    if (propertyInfo.Key == "ID")
    				dataFormItem = new DataFormNumericItem() { Name = propertyInfo.Key, Editor = "Numeric", MaximumNumberDecimalDigits = 0 };
    			else if (propertyInfo.Key == "Name")
    				dataFormItem = new DataFormTextItem() { Name = propertyInfo.Key, Editor = "Text" };
    			else
                    dataFormItem = new DataFormTextItem() { Name = propertyInfo.Key, Editor = "Text" };
    
    			items.Add(dataFormItem);
    		}
    
            return items;
        }
    }

    You can download the source code of this demo from GenerateDataFormItemsForDataObject

    Manually generate DataFormItems for data dictionary

    You can load the dataform with custom dictionary by generating DataFormItems manually. To create DataFormItems from dictionary, override the GenerateDataFormItems method.

  • c#
  • // dataform item creating using dictionary.
    dataForm.DataObject = new object();
    var dictionary = new Dictionary<string, object>();
    dictionary.Add("ID", 1);
    dictionary.Add("Name", "John");
    dataForm.ItemManager = new DataFormItemManagerExt(dataForm, dictionary);
    
    public class DataFormItemManagerExt : DataFormItemManager
    {
        Dictionary<string, object> dataFormDictionary;
        public DataFormItemManagerExt(SfDataForm dataForm, Dictionary<string, object> dictionary) : base(dataForm)
        {
            dataFormDictionary = dictionary;
        }
    
        protected override List<DataFormItemBase> GenerateDataFormItems(PropertyInfoCollection itemProperties, List<DataFormItemBase> dataFormItems)
        {
            var items = new List<DataFormItemBase>();
            foreach (var key in dataFormDictionary.Keys)
            {
                DataFormItem dataFormItem;
                if (key == "ID")
                    dataFormItem = new DataFormNumericItem() { Name = key, Editor = "Numeric", MaximumNumberDecimalDigits = 0 };
                else if (key == "Name")
                    dataFormItem = new DataFormTextItem() { Name = key, Editor = "Text" };
                else
                    dataFormItem = new DataFormTextItem() { Name = key, Editor = "Text" };
    
                items.Add(dataFormItem);
            }
             
            return items;
        }
    }

    Handling reading and writing values to and from the dictionary

    By default, the dictionary value will be shown in corresponding editor and value changes in editor will be committed again in dictionary value by using the GetValue and SetValue override methods in DataFormItemManager.

    Here, the value is read and written from/to dictionary instead of the data object.

  • c#
  • public class DataFormItemManagerExt : DataFormItemManager
    {
        Dictionary<string, object> dataFormDictionary;
        public DataFormItemManagerExt(SfDataForm dataForm, Dictionary<string, object> dictionary) : base(dataForm)
        {
            dataFormDictionary = dictionary;
        }
    
        public override object GetValue(DataFormItem dataFormItem)
        {
            var value = dataFormDictionary[dataFormItem.Name];
            return value;
        }
    
        public override void SetValue(DataFormItem dataFormItem, object value)
        {
            dataFormDictionary[dataFormItem.Name] = value;
        }
    
    }

    Here, the dataform is loaded with field from dictionary.

    You can download the source code of this demo from GenerateDataFormItemsForDictionary

    Binding with dynamic data object

    You can also load the dynamic object in SfDataForm DataObject and by default text editor will be generated for each dynamic object property. You can change the editor of DataFormItem for dynamic object property data type (default string) by using the AutoGeneratingDataFormItem event. You can find details about this here

    Limitations

    DynamicObject supports only in Xamarin.Forms Android and data form item will be created for each dynamic object property. Currently Dynamic object is not supported in UWP and iOS platform and you can find more details about this for iOS platform under the following links.

    https://forums.xamarin.com/discussion/53941/expandoobject-crashing-ios
    https://developer.xamarin.com/guides/ios/advanced_topics/limitations/

    dataForm.DataObject =new DynamicDataModel().ExpandoObject;
    dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;
    
    private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
    {
        if (e.DataFormItem != null && e.DataFormItem.Name == "DateOfBirth")
            e.DataFormItem.Editor = "Date";
    }
    
    public class DynamicDataModel
    {
        public dynamic ExpandoObject;
    
        public dynamic DynamicObject;
        public DynamicDataModel()
        {
            ExpandoObject = new ExpandoObject();
            ExpandoObject.FirstName = "John";
            ExpandoObject.LastName = "";
            ExpandoObject.DateOfBirth = DateTime.Now.Date;
            ExpandoObject.Email = "";
    
            DynamicObject = new Data();
            DynamicObject.FirstName = "John";
            DynamicObject.LastName = "";
            DynamicObject.DateOfBirth = DateTime.Now.Date;
            DynamicObject.Email = "";
        }
    }
    
    public class Data : DynamicObject, IDictionary<string, object>
    {
        Dictionary<string, object> list = new Dictionary<string, object>();
    
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            list[binder.Name] = value;
            return true;
        }
    
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            return list.TryGetValue(binder.Name, out result);
        }
    
        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return list.Keys;
        }
    
        public void Add(string key, object value)
        {
            this.list.Add(key, value);
        }
    
        public bool ContainsKey(string key)
        {
            return this.list.ContainsKey(key);
        }
    
        public ICollection<string> Keys
        {
            get { return this.list.Keys; }
        }
    
        public bool Remove(string key)
        {
            return this.list.Remove(key);
        }
    
        public bool TryGetValue(string key, out object value)
        {
            return this.list.TryGetValue(key, out value);
        }
    
        public ICollection<object> Values
        {
            get { return this.list.Values; }
        }
    
        object IDictionary<string, object>.this[string key]
        {
            get { return this.list[key]; }
            set { this.list[key] = value; }
        }
    
        public void Add(KeyValuePair<string, object> item)
        {
            this.list.Add(item.Key, item.Value);
        }
    
        public void Clear()
        {
            this.list.Clear();
        }
    
        public bool Contains(KeyValuePair<string, object> item)
        {
            return this.list.Contains(item);
        }
    
        public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
        {
    
        }
    
        public int Count
        {
            get { return this.list.Count; }
        }
    
        public bool IsReadOnly
        {
            get { return false; }
        }
    
        public bool Remove(KeyValuePair<string, object> item)
        {
            return this.list.Remove(item.Key);
        }
    
        public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
        {
            return this.list.GetEnumerator();
        }
    
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.list.GetEnumerator();
        }
    }

    Binding with dynamic data object in Xamarin.Forms DataForm

    You can download the sample from here

    Adding custom DataFormItems

    Support has been provided to generate custom DataFormItems for the defined business model using the Items property of the SfDataForm class. You need to set the AutoGenerateItems property to false to restrict the auto generation of DataFormItems.

    <?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:GettingStarted"
                            xmlns:dataForm ="clr-namespace:Syncfusion.XForms.DataForm;assembly=Syncfusion.SfDataForm.XForms"
                            x:Class="GettingStarted.MainPage">
        <ContentPage.BindingContext>
            <local:ViewModel x:Name="bindingContext"/>
        </ContentPage.BindingContext>
    
        <ContentPage.Content>
            <dataForm:SfDataForm x:Name="dataForm" DataObject="{Binding Details}"  AutoGenerateItems="false"> 
                <dataForm:SfDataForm.Items> 
                    <dataForm:DataFormTextItem Name="Name" Editor="Text"/> 
                    <dataForm:DataFormTextItem Name="Password" Editor="Password"/> 
                    <dataForm:DataFormMaskedEditTextItem Name="Phone" Editor="MaskedEditText"/> 
                    <dataForm:DataFormTextItem Name="Address" Editor="MultilineText"/> 
                    <dataForm:DataFormAutoCompleteItem Name="Countries" Editor="AutoComplete" ItemsSource = "{Binding CountryNames}"/> 
                    <dataForm:DataFormDateItem Name="BirthTime" Editor="Date"/> 
                </dataForm:SfDataForm.Items> 
            </dataForm:SfDataForm>
        </ContentPage.Content>
    </ContentPage>
    ObservableCollection<DataFormItemBase> items = new ObservableCollection<DataFormItemBase>();
    items.Add(new DataFormTextItem() { Name = "Name", Editor = "Text" });
    items.Add(new DataFormTextItem() { Name = "Password", Editor = "Password" });
    items.Add(new DataFormMaskedEditTextItem() { Name = "Phone", Editor = "MaskedEditText" });
    items.Add(new DataFormTextItem() { Name = "Address", Editor = "MultilineText" });
    items.Add(new DataFormAutoCompleteItem() { Name = "Countries", Editor = "AutoComplete", ItemsSource = this.GetItemSource("Countries")});
    items.Add(new DataFormTimeItem() { Name = "BirthTime", Editor = "Time" }); 
    dataForm.AutoGenerateItems = false; 
    dataForm.Items = items; 
    
     public class ViewModel
        {
            private DataFormModel details;
            private IList<string> countryNames;
            public ViewModel()
            {
                details = new DataFormModel();
                countryNames = new List<string>
                {
                    "United states",
                    "United Kingdom",
                    "France",
                    "Belgium",
                    "Germany"
                };
            }
    
            public DataFormModel Details
            {
                get { return this.details; }
                set { this.details = value; }
            }
            public IList<string> CountryNames
            {
                get { return this.countryNames; }
                set { this.countryNames = value; }
            }
        }
    
        private IList GetItemSource(string sourceName) 
        { 
            var list = new List<string>(); 
            if (sourceName == "Countries") 
            { 
                list.Add("Afghanistan");
                list.Add("Akrotiri");
                list.Add("Albania");
                list.Add("Algeria");
                list.Add("American Samoa");
                list.Add("Andorra");
                list.Add("Angola");
                list.Add("Anguilla");
                list.Add("Antarctica");
                list.Add("Antigua and Barbuda");
            } 
            return list; 
        }

    Dynamically add custom dataform items

    Support has been provided to dynamically add the dataform items to collections using the Items property of SfDataForm.

    dataForm.Items.Add(new DataFormDropDownItem() 
    				  { Name = "StateName", 
    					Editor = "DropDown", 
    					ItemsSource = this.GetItemSource("StateName"), 
    					PlaceHolderText = "Select a State" 
    				  });
    				
    dataForm.Items.Add(new DataFormItem() 
    				  { Name = "Save", 
    				    Editor = "Switch" 
    				  });

    Adding data form items in Xamarin.Forms DataForm

    Dynamically remove custom dataform items

    Support has been provided to dynamically remove the dataform items from collections using the Items property of SfDataForm.

    dataForm.Items.RemoveAt(2);

    Removing data form items in Xamarin.Forms DataForm

    Dynamically clear custom dataform items

    Support has been provided to dynamically clear the dataform items using the Items property of SfDataForm.

    dataForm.Items.Clear();

    Clear data form items in Xamarin.Forms DataForm

    Dynamically reset custom dataform items

    Support has been provided to reset the dataform items using the Items property of SfDataForm.

    var item = dataForm.Items[2];
    item = new DataFormNumericUpDownItem() { Name = "Age", Editor = "NumericUpDown" };
    dataForm.Items[2] = item;

    Dynamically add custom dataform group items

    Support has been provided to dynamically add custom group items using Items property of SfDataForm.

    DataFormGroupItem dataFormGroupItem = new DataFormGroupItem();
    dataFormGroupItem.GroupName = "GroupItem";
    dataFormGroupItem.IsExpanded = true;
    dataFormGroupItem.DataFormItems = new DataFormItems();
    
    dataFormGroupItem.DataFormItems.Add(new DataFormTextItem() { Name = "First Name", Editor = "Text", GroupName = "GroupItem" });
    dataFormGroupItem.DataFormItems.Add(new DataFormTextItem() { Name = "Middle Name", Editor = "Text", GroupName = "GroupItem" });
    dataFormGroupItem.DataFormItems.Add(new DataFormTextItem() { Name = "Last Name", Editor = "Text", GroupName = "GroupItem" });
    
    dataForm.Items.Add(dataFormGroupItem);

    Group data form items in Xamarin.Forms DataForm