Editing
3 Sep 202015 minutes to read
The data form supports several built-in editors.
Supported editors and associated DataFormItem
Editor name | Editor class | Data Type/Attribute | Input control loaded |
---|---|---|---|
Text | The String type property and any other type apart from the following specified cases. | ||
MultilineText | The String type property with multi line text. [DataType(DataType.Multiline)] | ||
Numeric | The property of Int, Double, Float, Decimal, Long types and also its nullable property. | ||
Percent | The property of Int, Double, Float, Decimal, Long types and also its nullable property with [DataType(“Percent”)] attribute. | ||
Currency | The property of Int, Double, Float, Decimal, Long types and also its nullable property with [DataType(DataType.Currency)] attribute. | ||
Date | The DateTime type property and the property with [DataType(DataType.Date)] and [DataType(DataType.DateTime)] attributes. | ||
Time | The property with [DataType(DataType.Time)] attribute. | ||
NumericUpDown | Int or Double type property. | ||
Segment | Enum type property. | ||
Bool | Bool type property. | ||
Switch | Bool type property. | ||
Picker | Enum and List type property. [EnumDataTypeAttribute] | ||
DropDown | Enum and List type property. [EnumDataTypeAttribute] | ||
Password | The String type property and property with [DataType(DataType.Password)] attribute. |
Changing editor for type
By default, the editors will be loaded based on the previous table. To change the editor for any type, use the RegisterEditor method and specify the type and editor.
dataForm.RegisterEditor(typeof(int), "NumericUpDown");
Here, the NumericUpDown
editor will be loaded for the integer type instead of numeric editor.
Changing editor for property
To change the editor for any property, use the RegisterEditor method and specify the property name and editor.
dataForm.RegisterEditor("IsAvailable", "Switch");
Here, the Switch editor will be loaded for the IsAvailable
property (bool type) instead of CheckBox
editor.
Customizing existing editor
The existing editors defined in the previous table can be customized by overriding the default editors.
Here, the DataFormTextEditor is customized to set different foreground for the FirstName property text editor.
public class CustomTextEditor : DataFormTextEditor
{
public CustomTextEditor(SfDataForm dataForm) : base(dataForm)
{
}
protected override void OnInitializeView(DataFormItem dataFormItem, EditText view)
{
if (dataFormItem.Name == "FirstName")
view.SetTextColor(Color.Green);
base.OnInitializeView(dataFormItem, view);
}
}
dataForm.RegisterEditor("Text", new CustomTextEditor(dataForm));
Creating new custom editor
Create the custom editor by overriding the DataFormEditor class.
Property settings, commit, data validation can be handled by overriding the required methods. Here, the EditText
is loaded for Age
editor.
public class CustomTextEditor : DataFormEditor<EditText>
{
public CustomTextEditor(SfDataForm dataForm) : base(dataForm)
{
}
protected override EditText OnCreateEditorView()
{
return new EditText(this.dataForm.Context);
}
protected override void OnInitializeView(DataFormItem dataFormItem, EditText view)
{
base.OnInitializeView(dataFormItem, view);
}
protected override void OnWireEvents(EditText view)
{
view.TextChanged += OnViewTextChanged;
view.FocusChange += OnViewFocusChange;
}
private void OnViewFocusChange(object sender, View.FocusChangeEventArgs e)
{
var view = sender as EditText;
view.SetTextColor(Color.Red);
if (this.DataForm.CommitMode == CommitMode.LostFocus || this.DataForm.ValidationMode == ValidationMode.LostFocus)
this.OnValidateValue(view);
if (this.DataForm.CommitMode != CommitMode.LostFocus) return;
this.OnCommitValue(view);
OnValidateValue(sender as EditText);
}
private void OnViewTextChanged(object sender, Android.Text.TextChangedEventArgs e)
{
var view = sender as EditText;
if (DataForm.CommitMode == CommitMode.PropertyChanged || DataForm.ValidationMode == ValidationMode.PropertyChanged)
this.OnValidateValue(view);
if (this.DataForm.CommitMode != CommitMode.PropertyChanged) return;
this.OnCommitValue(view);
}
private void OnViewPropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnValidateValue(sender as EditText);
}
protected override bool OnValidateValue(EditText view)
{
return this.DataForm.Validate("Age");
}
protected override void OnCommitValue(EditText view)
{
var dataFormItemView = view.Parent as DataFormItemView;
this.DataForm.ItemManager.SetValue(dataFormItemView.DataFormItem, view.Text);
}
protected override void OnUnWireEvents(EditText view)
{
view.TextChanged -= OnViewTextChanged;
view.FocusChange -= OnViewFocusChange;
}
}
dataForm.RegisterEditor("numeric", new CustomTextEditor(dataForm));
dataForm.RegisterEditor("Age", "numeric");
dataForm.ValidationMode = ValidationMode.LostFocus;
You should manually commit the custom DataFormItem editor value by using OnCommitValue override method of DataFormEditor class on custom editor Value
or Focus changed
event which is used to update the custom editor value in respective property in DataObject based on dataform commit mode set.
Also , you should manually validate the custom editor value in by using OnValidateValue override method of DataFormEditor
class on custom editor Value
or Focus changed
event which is used to validate the custom editor value based on data form validation mode set. In the override method for OnValidateValue, you need to return DataForm.Validate(string) method in order to validate the particular data item.
Support for Email editor
You can load the Email editor by changing input type in the AutoGeneratingDataFormItem event.
dataForm.AutoGeneratingDataFormItem += DataForm_AutoGeneratingDataFormItem;
private void DataForm_AutoGeneratingDataFormItem(object sender, AutoGeneratingDataFormItemEventArgs e)
{
if (e.DataFormItem.Name == "Email")
(e.DataFormItem as DataFormTextItem).InputType = Android.Text.InputTypes.TextVariationEmailAddress;
}
Commit mode
The CommitMode determines when the value should be committed to the data object.
The supported commit modes are as follows:
- LostFocus
- PropertyChanged
- Explicit
dataForm.CommitMode = CommitMode.LostFocus;
LostFocus
If the commit mode is LostFocus, the value is committed when the editor lost its focus.
PropertyChanged
The value will be committed immediately when it is changed.
Explicit
The value should be committed manually by calling the SfDataForm.Commit or SfDataForm.Commit(propertyName) method.
The following code commits the value of all the properties in the data object:
dataForm.Commit();
To commit the specific property value, pass the property name as argument.
dataForm.Commit("Name");
Update editor value based on another editor
You can the update the editor value by using the SfDataForm.UpdateEditor method at runtime.
var expenseInfo = new ExpenseInfo();
expenseInfo.PropertyChanged += ExpenseInfo_PropertyChanged;
dataForm.DataObject = expenseInfo;
SetContentView(dataForm);
private void ExpenseInfo_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Budget" || e.PropertyName == "Expense")
{
var item = sender as ExpenseInfo;
item.Balance = item.Budget - item.Expense;
dataForm.UpdateEditor("Balance");
}
}
Here, the Balance property value is updated based on Budget and Expense properties. For updating value in editor, the UpdateEditor
method is called.
You can download the sample from here.
Converter
To show the original value in different format or as different value, use the Converter attribute.
Changing original value of the DataForm property value using converter
Here, the original value is multiplied by 10 and shown in editor. While committing, it is divided by 10 and stored in the data object.
public class ValueConverterExt : IPropertyValueConverter
{
public object Convert(object value)
{
var amount = double.Parse(value.ToString());
return amount * 10;
}
public object ConvertBack(object value)
{
var amount = double.Parse(value.ToString());
return amount / 10;
}
}
private double? amount = 1000;
[Converter(typeof(ValueConverterExt))]
public double? Amount
{
get
{
return amount;
}
set
{
amount = value;
RaisePropertyChanged("Amount");
}
}
Using date editor for DateTimeOffset DataForm property data type
In SfDataForm, you cannot use date editor for DateTimeOffset
property data type. To overcome this, you need to use Converter
attribute to convert DateTimeOffset
to DateTime
value and vice-versa.
private DateTimeOffset displayDate;
[Converter(typeof(ValueConverterExt))]
public DateTimeOffset DisplayDate
{
get
{
return displayDate;
}
set
{
displayDate = value;
}
}
public class ValueConverterExt : IPropertyValueConverter
{
public object Convert(object value)
{
DateTime baseTime = new DateTime(2008, 6, 19, 7, 0, 0);
DateTime targetTime;
var dateTimeOffset = (DateTimeOffset)value;
dateTimeOffset = new DateTimeOffset(baseTime,
TimeZoneInfo.Local.GetUtcOffset(baseTime));
targetTime = dateTimeOffset.DateTime;
return targetTime;
}
public object ConvertBack(object value)
{
var dateTime = (DateTime)value;
dateTime = new DateTime(2008, 6, 19, 7, 0, 0);
dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Local);
DateTimeOffset dateTimeOffset = dateTime;
return dateTimeOffset;
}
}
You can download the source code of this demo from here DateTimeOffsetConverter
Disable editing
You can disable editing by setting the IsReadOnly property of the data form.
dataForm.IsReadOnly = true;
You can also change the editing behavior by setting the IsReadOnly property of the DataFormItem.
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;
}
}
You can also change the editing behavior at runtime.
private void Button_Click(object sender, System.EventArgs e)
{
var dataFormItem = dataForm.ItemManager.DataFormItems["FirstName"];
dataFormItem.IsReadOnly = true;
}
NOTE
DataFormItem.IsReadOnly takes higher priority than SfDataForm.IsReadOnly.
You can also have option to define the editing behavior from SfDataForm.DataObject
definition using the ReadOnly attribute and EditableAttribute.
private double? balance;
[ReadOnly(true)]
public double? Balance
{
get
{
return balance;
}
set
{
balance = value;
RaisePropertyChanged("Balance");
}
}
private double? balance;
[Editable(false)]
public double? Balance
{
get
{
return balance;
}
set
{
balance = value;
RaisePropertyChanged("Balance");
}
}
You can also define the editing behavior by defining the SfDataForm.DataObject fields definition without setter
or with private set
.
private double? balance;
public double? Balance
{
get
{
return balance;
}
}
private double? balance;
public double? Balance
{
get
{
return balance;
}
private set
{
balance = value;
}
}