sfDataGrid - Crash on editable cell when LostFocusBehavior.EndEditCurrentCell is set

When on sfDataGrid I exit after editing the cell and EndEditCurrentCell is set, app crashes with exception:

**System.NotSupportedException:** 'Unable to activate instance of type Xamarin.Forms.Platform.Android.FormsEditText from native handle 0x7fd0c38244 (key_handle 0xb8bcf4b).'


XAML grid data




   <sfgrid:SfDataGrid x:Name="dataGrid"
ItemsSource="{Binding P}"
AllowEditing="True"
EditTapAction="OnTap"
SelectionMode="SingleDeselect"
NavigationMode="Cell"
LostFocusBehavior="EndEditCurrentCell"
AutoGenerateColumns="False"
EditorSelectionBehavior="SelectAll">

 <sfgrid:GridTextColumn HeaderText="Unit" MappingName="Unit" />




public string Unit { get; private set; }

2 Replies

RO Ryszard Ochodzki September 13, 2021 11:38 AM UTC

More information:


Forms version 5.0.0.2083+716-sha.ec1520e32-azdo.4968107

DataGrid version 19.2.0.60

Android targetsdk 30



This is happening on Android, if not already obvious from the exception...


Changing backing field to public setter does not change anything.

public string Unit { get; set; }





KK Karthikraja Kalaimani Syncfusion Team September 14, 2021 05:18 AM UTC

Hi Rys, 

We have checked the reported issue and we found a workaround to achieve your requirement. Please refer to the below code snippets and attached sample. 

Code snippets : 
 
  this.dataGrid.CellRenderers.Remove("Numeric");
            this.dataGrid.CellRenderers.Add("Numeric", new CustomNumericRenderer());
....
 
    public class CustomNumericRenderer : GridCellNumericRenderer 
    { 
        public CustomNumericRenderer() 
        { 
        } 
  
        protected override SfNumericTextBoxExt OnCreateEditUIView() 
        { 
            var view = new CustomNumericTextBox(); 
            view.Completed += View_Completed; 
            view.Unfocused += View_Unfocused; 
            return view; 
        } 
  
        private async void View_Unfocused(object sender, FocusEventArgs e) 
        { 
            await Task.Delay(10); 
            this.DataGrid.EndEdit(); 
            //throw new NotImplementedException(); 
        } 
  
        private async void View_Completed(object sender, EventArgs e) 
        { 
            await Task.Delay(10); 
            this.DataGrid.EndEdit(); 
            //throw new NotImplementedException(); 
        } 
    } 
  
    public class CustomNumericTextBox : SfNumericTextBoxExt 
    { 
        /// <summary> 
        /// Initializes a new instance of the <see cref="NumericTextBoxView"/> class. 
        /// </summary> 
        public CustomNumericTextBox() 
        { 
        } 
    }

// Android Renderer

using System;
 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using Android.App; 
using Android.Content; 
using Android.OS; 
using Android.Runtime; 
using Android.Views; 
using Android.Views.InputMethods; 
using Android.Widget; 
using DataGridDemo; 
using Syncfusion.SfDataGrid.XForms.Droid; 
using Syncfusion.SfDataGrid.XForms.Renderers; 
using Syncfusion.SfNumericTextBox.XForms.Droid; 
using Xamarin.Forms; 
using Xamarin.Forms.Platform.Android; 
using static Android.Views.View; 
  
[assembly: ExportRenderer(typeof(CustomNumericTextBox), typeof(CustomRenderer))] 
  
namespace Syncfusion.SfDataGrid.XForms.Droid 
{ 
    /// <summary> 
    /// Represents the <see cref="SfNumericTextBoxExtRenderer"/> used to modify the <see cref="SfNumericTextBoxExt"/> for android platform. 
    /// </summary> 
    internal class CustomRenderer : SfNumericTextBoxRenderer 
    { 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed. Suppression is OK here. Private field does not need documentation.")] 
        private GridCell gridCell; 
  
        /// <summary> 
        /// Initializes a new instance of the <see cref="SfNumericTextBoxExtRenderer"/> class. 
        /// </summary> 
        public CustomRenderer() 
        { 
        } 
  
        /// <summary> 
        /// Gets or sets the <see cref="GridCell"/>. 
        /// </summary> 
        private GridCell GridCell 
        { 
            get { return this.gridCell; } 
            set { this.gridCell = null; } 
        } 
  
        /// <summary> 
        ///  Dispatch a key event before it is processed by any input method associated with the view hierarchy. 
        /// </summary> 
        /// <param name="e"><see cref="KeyEvent"/>.</param> 
        /// <returns>Returns whether event is handled.</returns> 
        public override bool DispatchKeyEventPreIme(KeyEvent e) 
        { 
            if (e.KeyCode == Keycode.Back && e.Source == InputSourceType.Keyboard) 
            { 
                this.ClearFocus(); 
                return true; 
            } 
  
            return base.DispatchKeyEventPreIme(e); 
        } 
  
        /// <summary> 
        /// Occurs when the element is changed. 
        /// </summary> 
        /// <param name="e">ElementChangedEventArgs for <see cref="SfNumericTextBox.XForms.SfNumericTextBox"/> that contains event data.</param> 
        protected override void OnElementChanged(ElementChangedEventArgs<SfNumericTextBox.XForms.SfNumericTextBox> e) 
        { 
            base.OnElementChanged(e); 
            if (e.NewElement != null && this.Control != null) 
            { 
                if (this.GridCell != null) 
                { 
                    if (this.GridCell.DataColumn.Renderer.DataGrid.ImeOptions == GridImeOptions.NoExtractUi) 
                    { 
                        this.Control.ImeOptions = (ImeAction)ImeFlags.NoExtractUi; 
                    } 
                    else 
                    { 
                        this.Control.ImeOptions = ImeAction.Done; 
                    } 
                } 
            } 
        } 
  
        /// <summary> 
        /// Occurs when property of the <see cref="SfNumericTextBoxExt"/> is changed. 
        /// </summary> 
        /// <param name="sender">The instance of <see cref="SfDataGrid"/>.</param> 
        /// <param name="e">The <see cref="PropertyChangedEventArgs"/>.</param> 
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) 
        { 
            base.OnElementPropertyChanged(sender, e); 
            
            if (e.PropertyName == "Renderer") 
            { 
                this.gridCell = this.Element.Parent != null ? this.Element.Parent as GridCell : null; 
            } 
        } 
  
        /// <summary> 
        /// Releases the unmanaged resources used by the component and optionally releases the managed resources. 
        /// </summary> 
        /// <param name="disposing"> if true - release both managed and unmanaged resources; 
        /// if false - release only unmanaged resources. 
        /// </param> 
        protected override void Dispose(bool disposing) 
        { 
            this.GridCell = null; 
            base.Dispose(disposing); 
        } 
    } 
} 


Loader.
Up arrow icon