Working with DataForm
3 Sep 202016 minutes to read
Auto-generating DataFormItems for Data field
By default, DataFormItems will be generated based on type of property. For example, DataFormNumericItem will be created for int
type property.
DataFormItem generation depends on the type and attribute defined for the property. The following table lists the several types of DataFormItem
and its constraints for auto generation.
Generated DataFormItem Type | Editor | Data Type / Attribute |
---|---|---|
Text | Default DataFormItem generated for string type and the properties with below attributes. [DataType(DataType.Text)] [DataType(DataType.MultilineText)] [DataType(DataType.Password)] | |
Numeric | Generated for int, double, float, decimal, long types and its nullable also properties with below attributes. [DataType(DataType.Currency)] [DataType("Percent")] | |
Date | Generated for DateTime type and properties with below attributes. [DataType(DataType.Date)] [DataType(DataType.DateTime)] | |
Time | Generated for the property with below attribute. [DataType(DataType.Time)] | |
Picker | Generated for Enum type property and the property with below attribute. [EnumDataTypeAttribute] | |
Bool | Bool type |
You can customize the property settings or cancel the generation of DataFormItem
by handling AutoGeneratingDataFormItem event.
Customize auto generated fields
You can customize or cancel the generated DataFormItem
by handling AutoGeneratingDataFormItem event. AutoGeneratingDataFormItem
event occurs when the field is auto-generated for public and non-static property of the data object.
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 data field
You can cancel the specific DataFormItem adding to the DataForm by handling AutoGeneratingDataFormItem
event or by defining display attribute to avoid the particular data field being displayed in DataForm.
Using attributes
You can use Bindable attribute or set AutoGenerateField as false
for canceling DataFormItem
generation.
private int id;
[Display(AutoGenerateField = false)]
public int ID
{
get
{
return id;
}
set
{
id = value;
RaisePropertyChanged("ID");
}
}
private string middleName;
[Bindable(false)]
public string MiddleName
{
get { return this.middleName; }
set
{
this.middleName = value;
}
}
Using event
In the below code, DataFormItem
generation for MiddleName
property is canceled by setting 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 DataFormItem in AutoGeneratingDataFormItem
event.
In the below code, editor is changed for Name
field from Picker
to DropDown
.
dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;
private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
{
if (e.DataFormItem.Name == "Name")
e.DataFormItem.Editor = "DropDown";
}
Changing property settings
You can change the property of DataFormItem in AutoGeneratingDataFormItem
event.
Here, Salary
data field is restricted from being edited in DataForm.
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;
}
}
Setting Watermark
You can display watermark in editor by defining display attribute or using AutoGeneratingDataFormItem
event.
Using attribute
You can show watermark in editor by setting 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 watermark in editor by using 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 created DataFormItem and assign new DataFormItem
based on your requirement.
Here,DataFormTextItem with number keyboard loaded for numeric value instead of DataFormNumericItem.
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", KeyBoardType = UIKeyboardType.NumberPad };
}
}
Adding or removing Data field displayed in DataForm at runtime
If you want to remove or add data fields item at runtime, you can use RefreshLayout method which auto-generates the DataFormItem’s where you can skip certain item from display. By default, it will generate the items that was canceled initially. If you want to regenerate all the items, you need to pass argument as true
.
In the below 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 DataForm at runtime.
dataForm = new SfDataForm(new CoreGraphics.CGRect(0, 45, this.View.Frame.Width, this.View.Frame.Height - 30));
dataForm.DataObject = new ContactsInfo();
dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;
var button = new UIButton(new CoreGraphics.CGRect(0, this.View.Frame.Height - 30, this.View.Frame.Width, 30));
button.SetTitle("More Fields", UIControlState.Normal);
button.SetTitleColor(UIColor.Black, UIControlState.Normal);
button.TouchDown += Button_TouchDown;
View.AddSubview(dataForm);
View.AddSubview(button);
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;
}
}
}
If you want to generate MiddleName and LastName fields at runtime, you need to set refreshLayout
flag as true
and call RefreshLayout method which triggers AutoGeneratingDataFormItem
event again and generates the items based on refreshLayout
flag.
private void Button_TouchDown(object sender, EventArgs e)
{
refreshLayout = true;
dataForm.RefreshLayout();
}
Here, MiddleName
and LastName
fields are generated at runtime after clicking more field button.
GroupName
field is displayed initially in DataForm. If you want to remove it at runtime, you need to set refreshLayout flag as true and pass argument as true inRefreshLayout method. It triggers AutoGeneratingDataFormItem
event for all the fields where you can cancel `GroupName’ field item generation.
private void Button_TouchDown(object sender, EventArgs e)
{
refreshLayout = true;
dataForm.RefreshLayout(true);
}
Here, GroupName field is removed at runtime.
You can download the sample from here.
DataFormItemManager
DataFormItemManager creates DataFormItems collection and handles value reflection and validation. It also provides overrides to handle get and set property values from and to data object.
Manually generate DataFormItems for DataObject
By default, DataFormItems will be generated based on data object. If you need to generate DataFormItems
manually, override DataFormItemManager class and set it to SfDataForm.ItemManager.
To create DataFormItems
, override the GenerateDataFormItems method.
public class DataFormItemManagerExt : DataFormItemManager
{
public SfDataForm sfDataForm;
public DataFormItemManagerExt(SfDataForm dataForm) : base(dataForm)
{
sfDataForm = dataForm;
}
protected override List<DataFormItemBase> GenerateDataFormItems(PropertyDescriptorCollection itemProperties, List<DataFormItemBase> dataFormItems)
{
var items = new List<DataFormItemBase>();
foreach (PropertyDescriptor propertyInfo in itemProperties)
{
DataFormItem dataFormItem;
if (propertyInfo.Name == "ContactNumber")
dataFormItem = new DataFormTextItem() { Name = propertyInfo.Name, Editor = "Text", InputType = Android.Text.InputTypes.ClassNumber };
else if (propertyInfo.Name == "FirstName")
dataFormItem = new DataFormTextItem() { Name = propertyInfo.Name, Editor = "Text" };
else
dataFormItem = new DataFormTextItem() { Name = propertyInfo.Name, Editor = "Text" };
items.Add(dataFormItem);
}
return items;
}
}
dataForm.DataObject = new ContactsInfo();
dataForm.ItemManager = new DataFormItemManagerExt(dataForm);
You can download the source code of this demo from GenerateDataFormItemsForDataObject
Manually generate DataFormItems for data dictionary
You can load dataform with custom dictionary by generating DataFormItems manually. To create DataFormItems
from dictionary, override the GenerateDataFormItems method.
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(PropertyDescriptorCollection 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;
}
}
var dictionary = new Dictionary<string, object>();
dictionary.Add("ID", 1);
dictionary.Add("Name", "John");
dataForm.ItemManager = new DataFormItemManagerExt(dataForm, dictionary);
Here, the dataform is loaded with field from dictionary.
Handling reading and writing value to and from 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, value is read and written from/to dictionary instead of data object.
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;
}
}
You can download the source code of this demo from GenerateDataFormItemsForDictionary