Articles in this section
Category / Section

How to add floating label text editor in DataForm Xamarin.Forms?

2 mins read

DataForm allows you to add custom editor by inheriting DataFormEditor class which is used to add custom editor by passing custom view in it.

 

This article explains adding custom text editor with floating label support in data form.

Here Name property is used as custom editor.

 

ContactInfo.cs
 
public class ContactInfo : NotificationObject
    {
        private string id;
 
        [Required(AllowEmptyStrings = false, ErrorMessage = "Id should not be empty")]
        [Display(Prompt = "Id")]
 
        public string ID
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
                RaisePropertyChanged("ID");
            }
        }
 
        private string name;
 
        [DisplayOptions(RowSpan = 2)]
        [Required(AllowEmptyStrings = false, ErrorMessage = "Name should not be empty")]
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                RaisePropertyChanged("Name");
            }
        }
    }
 

 

 

By passing custom view in DataFormEditor class, you can add the custom editor in data form. You can refer to the data form user guide documentation for creating new custom editor.

 

https://help.syncfusion.com/xamarin/sfdataform/editing#creating-new-custom-editor

 

Here, Entry is loaded for custom floating label text editor in dataForm. The custom view (Entry) property settings, commit, and data validation can be handled by overriding required methods in the DataFormEditor class.

 

Refer to the following code example for binding the DataObject and adding custom editor using RegisterEditor method in data form.

 

 
            dataForm.RegisterEditor("Entry", new CustomEntryEditor(dataForm));
            dataForm.RegisterEditor("Name", "Entry");
            dataForm.LabelPosition = LabelPosition.Top;
            dataForm.DataObject = new ContactInfo();

 

And customized each platform renderer to show the floating label text layout as native control for custom editor(CustomEntry).

 

In Android Renderer:

 

Here, TextInputLayout is loaded as native control which wraps an EditText to show a floating label in editor.

 

Hint property of EditText handled to display the floating label (PlaceholderText) while entering the text, also customized the EditText view in renderer.

 

 
[assembly: ExportRenderer(typeof(CustomEntry), typeof(FloatingLabel_Forms.Droid.CustomEntryRenderer))]
namespace FloatingLabel_Forms.Droid
{
   public class CustomEntryRenderer : Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<Entry, TextInputLayout>
    {
        private EditText _defaultEditTextForValues;
        private bool _preventTextLoop;
 
        private CustomEntry CustomEntry { get; set; }
        private EditText EditText => Control.EditText;
 
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
 
            if (e.NewElement != null)
            {
                var nativeControl = CreateNativeControl();
                CustomEntry = e.NewElement as CustomEntry;
                SetNativeControl(nativeControl);
                _defaultEditTextForValues = new EditText(Context);
 
                Focusable = true;
                Control.HintEnabled = true;
                Control.HintAnimationEnabled = true;
                EditText.ShowSoftInputOnFocus = true;
 
                EditText.FocusChange += ControlOnFocusChange;
                EditText.ImeOptions = ImeAction.Done;
 
                SetBorder((e.NewElement as CustomEntry).BottomBorderColor.ToAndroid());
            }
        }
 
        private void ControlOnFocusChange(object sender, FocusChangeEventArgs args)
        {
            if (args.HasFocus)
            {
                var manager = (InputMethodManager)Application.Context.GetSystemService(Context.InputMethodService);
 
                EditText.PostDelayed(() =>
                {
                    EditText.RequestFocus();
                    manager.ShowSoftInput(EditText, 0);
                },
                    100);
            }
        }
 
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
 
            if (e.PropertyName == Entry.PlaceholderProperty.PropertyName)
            {
                SetHintText();
            }
        }          
 
        private void SetHintText()
        {
            Control.Hint = Element.Placeholder;
        }
 
        protected override TextInputLayout CreateNativeControl()
        {
            var layout = (TextInputLayout)LayoutInflater.From(Context).Inflate(Resource.Layout.TextInputLayout, null);
            var inner = layout.FindViewById(Resource.Id.textInputEdit);
            if (!string.IsNullOrWhiteSpace(Element.AutomationId))
            {
                inner.ContentDescription = Element.AutomationId;
            }
 
            return layout;
        }
    }

 

In iOS Renderer:

 

Here, UITextField control is loaded as native control. And by using LayoutSubviews override method added the sub views (UILabel) to display the floating label in editor.

 
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
 
namespace FloatingLabel_Forms.iOS
{
    public class CustomEntryRenderer : ViewRenderer<CustomEntry, FloatLabeledTextField>
    {
 
        private readonly CGColor _defaultLineColor = Xamarin.Forms.Color.FromHex("#e0e7ec").ToCGColor();
        private readonly CGColor _editingUnderlineColor = UIColor.Blue.CGColor;
        private UIColor _defaultPlaceholderColor = UIColor.Red;
        private UIColor _defaultTextColor;
        private IElementController ElementController => Element as IElementController;
 
        protected override void OnElementChanged(ElementChangedEventArgs<CustomEntry> e)
        {
            base.OnElementChanged(e);
 
            var base_entry = Element as CustomEntry;
 
            if (e.OldElement != null)
            {
                Control.EditingChanged -= ViewOnEditingChanged;
            }
 
            if (e.NewElement != null)
            {
                var nativeControl = CreateNativeControl();
                SetNativeControl(nativeControl);
 
                if (!string.IsNullOrWhiteSpace(Element.AutomationId))
                    SetAutomationId(Element.AutomationId);
 
                _defaultTextColor = Control.FloatingLabelTextColor;
                _defaultPlaceholderColor = Control.FloatingLabelTextColor;
 
                Control.ErrorTextIsVisible = true;
                Control.EditingChanged += ViewOnEditingChanged;                
            }
 
            if(Control != null && base_entry != null)
            {
                SetReturnType(base_entry);
 
                Control.ShouldReturn += (UITextField textField) =>
                {
                    base_entry?.InvokeCompleted();
                    return true;
                };
            }
        }
}
 
       protected virtual FloatLabeledTextField CreateNativeControl()
        {
            return new FloatLabeledTextField();
     }
 
        private void SetHintText()
        {
            Control.Placeholder = Element.Placeholder;
     }
 
         protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
 
            if (e.PropertyName == PlaceholderProperty.PropertyName)
                SetHintText();
     }
 

 

In UWP Renderer:

 

Here TextBox control loaded as native control .

 

To display the floating label in editor, TextBox control Header property value set as PlaceholderText when control get focused to enter the text and control unfocused reset the Header property value to empty to remove the floating label in editor .

 

Also overridden the default style of TextBox is to customize the border style on loading and customized the PlaceholderText, header text color and border color on pointer over.

 

 
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace FloatingLabel_Forms
{
    public class CustomEntryRenderer : EntryRenderer
    {
        internal TextBox NativeTextBox { get; set; }
        internal string PlaceholderText { get; set; }
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Entry> e)
        {
            base.OnElementChanged(e);
 
            if (Control != null && Element is CustomEntry)
            {
                PlaceholderText = Control.PlaceholderText;
                Control.Style = (Style)Application.Current.Resources["FloatingLabelStyle"];
                NativeTextBox = Control as TextBox;
 
                NativeTextBox.GotFocus += NativeTextBox_GotFocus;
                NativeTextBox.LostFocus += NativeTextBox_LostFocus;
 
                NativeTextBox.BorderBrush = new SolidColorBrush(Colors.Green);
 
                if (!string.IsNullOrEmpty(NativeTextBox.Text))
                    NativeTextBox.Header = NativeTextBox.PlaceholderText;
            }
        }
 

 

To download the sample, click FloatingLabelTextEditor

 

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied