How to add custom Password editor in SfDataForm?
SfDataForm allows you to add custom editor by overriding the DataFormEditor class which is used to add custom view in data form.
This article explains adding custom Password editor in SfDataForm.
Company.cs: public class Company { public string Name { get; set; } public string Addresses { get; set; } public string Password { get; set; } }
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 Password editor.
public class CustomPasswordEntry : Entry { public CustomPasswordEntry() {
} }
|
The custom view (Entry) property settings, commit, and data validation can be handled by overriding required methods in the DataFormEditor class.
Here, the IsPassword property is set to true to load the Password editor using OnInitializeView override method which is used to change the custom view property settings.
Manually commit the custom DataFormItem editor value by using the OnCommitValue override method of DataFormEditor class on the custom editor TextChanged event which is used to update the custom editor value in the DataObject property of SfDataForm.
Manually validate the custom editor value by using the OnValidateValue override method of DataFormEditor class on the custom editor Unfocused event which is used to validate the custom editor value in data form.
public class CustomPasswordEditor : DataFormEditor<CustomPasswordEntry> { public CustomPasswordEditor(SfDataForm dataForm) : base(dataForm) { } protected override CustomPasswordEntry OnCreateEditorView() { return new CustomPasswordEntry(); } protected override void OnInitializeView(DataFormItem dataFormItem, CustomPasswordEntry view) { view.IsPassword = true; view.Placeholder = "Enter value"; view.PlaceholderColor = Color.White; } protected override void OnWireEvents(CustomPasswordEntry view) { view.TextChanged += View_TextChanged; view.Unfocused += View_Unfocused; } protected override bool OnValidateValue(CustomPasswordEntry view) { return DataForm.Validate("Password"); } private void View_Unfocused(object sender, FocusEventArgs e) { OnValidateValue(sender as CustomPasswordEntry); } private void View_TextChanged(object sender, TextChangedEventArgs e) { OnCommitValue(sender as CustomPasswordEntry); } protected override void OnCommitValue(CustomPasswordEntry view) { var dataFormItemView = view.Parent as DataFormItemView; var textValue = view.Text; this.DataForm.ItemManager.SetValue(dataFormItemView.DataFormItem, view.Text); } }
Refer to the following code example for binding the DataObject and adding custom editor using the RegisterEditor method as Password editor in data form.
dataForm = bindable as SfDataForm; if (Device.RuntimePlatform == Device.UWP) { dataForm.RegisterEditor("PasswordEditor", new CustomPasswordEditor(dataForm)); dataForm.RegisterEditor("Password", "PasswordEditor"); } dataForm.DataObject = new Company(); dataForm.ValidationMode = ValidationMode.LostFocus;
You can also customize or change the default appearance of loaded custom editor view in custom renderer platform by using the OnElementChanged override method of ViewRenderer. By using the SetNativeControl method, you can set the native platform control for loaded custom editor.
This article explains custom renderer in SfDataForm for Xamarin.Forms.UWP platform alone.
Here, PasswordBox loaded as native control for custom Password editor in Xamarin.Forms.UWP platform, accessed the RevealButton which is the template child of PasswordBox, and raised the Click event for RevealButton to show the text of the PasswordBox control on RevealButton clicked by setting the PasswordBox property PasswordRevealMode as Visible.
Refer to the following code example to set the native control as PasswordBox in renderer.
[assembly: ExportRenderer(typeof(CustomPasswordEntry), typeof(CustomPasswordRenderer))] namespace PasswordCustomization.UWP { public class CustomPasswordRenderer : ViewRenderer<Xamarin.Forms.Entry, PasswordBox> { internal PasswordBox NativePasswordBox { get; set; } internal string PlaceholderText { get; set; } internal object RevealButton { get; set; } protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Entry> e) { base.OnElementChanged(e); NativePasswordBox = new PasswordBox(); NativePasswordBox.Loaded += NativePasswordBox_Loaded; if (Element is CustomPasswordEntry) { PlaceholderText = NativePasswordBox.PlaceholderText; NativePasswordBox.Foreground = new SolidColorBrush(Colors.Blue); NativePasswordBox.FontSize = 12; NativePasswordBox.Style = (Style)Application.Current.Resources["CustomPasswordBoxStyle"]; NativePasswordBox.PointerEntered += Control_PointerEntered; NativePasswordBox.PointerExited += Control_PointerExited; NativePasswordBox.GotFocus += NativeTextBox_GotFocus; NativePasswordBox.LostFocus += NativeTextBox_LostFocus; NativePasswordBox.BorderBrush = new SolidColorBrush(Colors.ForestGreen); NativePasswordBox.PasswordChanged += NativePasswordBox_PasswordChanged; NativePasswordBox.PlaceholderText = "Enter value"; this.SetNativeControl(NativePasswordBox); } } //Since native control is newly initialized you have to update the native control Text to custom view. //Here, Element is CustomPasswordEntry which is custom view of Xamarin.Forms. private void NativePasswordBox_PasswordChanged(object sender, RoutedEventArgs e) { Element.Text = NativePasswordBox.Password; } private void NativePasswordBox_Loaded(object sender, RoutedEventArgs e) { MethodInfo TemplateChildMethod = NativePasswordBox.GetType().GetMethod("GetTemplateChild", BindingFlags.NonPublic | BindingFlags.Instance); RevealButton = TemplateChildMethod.Invoke(NativePasswordBox, new object[] { "RevealButton" }); if (RevealButton != null && RevealButton is Windows.UI.Xaml.Controls.Primitives.ToggleButton) { (RevealButton as Windows.UI.Xaml.Controls.Primitives.ToggleButton).Click += CustomPasswordRenderer_Click; } } private void CustomPasswordRenderer_Click(object sender, RoutedEventArgs e) { NativePasswordBox.PasswordRevealMode = PasswordRevealMode.Visible; if (RevealButton != null) (RevealButton as Windows.UI.Xaml.Controls.Primitives.ToggleButton).Visibility = Visibility.Visible; } private void Control_PointerExited(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e) { this.NativePasswordBox.Foreground = new SolidColorBrush(Colors.Gray); } private void Control_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e) { this.NativePasswordBox.Foreground = new SolidColorBrush(Colors.Blue); } } }
The default style of PasswordBox control is overridden to customize the pointer over PlaceholderText and border color by using the GotFocus, LostFocus, PointerEntered, and PointerExited events. The PasswordRevealMode property of PasswordBox control is changed as Peek in the LostFocus event to hide the text visible on focus lost.
private void NativeTextBox_LostFocus(object sender, RoutedEventArgs e) { NativePasswordBox.PlaceholderText = PlaceholderText; NativePasswordBox.PasswordRevealMode = PasswordRevealMode.Peek; if (RevealButton != null) (RevealButton as Windows.UI.Xaml.Controls.Primitives.ToggleButton).Visibility = Visibility.Collapsed; if (string.IsNullOrEmpty(NativePasswordBox.Password)) { NativePasswordBox.Header = string.Empty; NativePasswordBox.PlaceholderText = Element.Placeholder; } } private void NativeTextBox_GotFocus(object sender, RoutedEventArgs e) { NativePasswordBox.PlaceholderText = string.Empty; if (RevealButton != null) (RevealButton as Windows.UI.Xaml.Controls.Primitives.ToggleButton).Visibility = Visibility.Visible; if (string.IsNullOrEmpty(NativePasswordBox.Password)) NativePasswordBox.Password = string.Empty; }
Click here to download the sample.