When displaying textual information to your user, you want it to be well displayed with good font size, appropriate style, text color… But you also want the user to edit this information with minimum efforts. You can build a custom control in Xamarin Forms for this purpose. Let’s say you have a page in your app with a title, or several labels containing text. And you want the user to edit these as he wish, without switching to a new page. A good scenario will be to tap on the label and edit the test as it focus and display the text as it was, when focus is lost.

This is seen already in several applications. It could be achieved easily in Xamarin Forms by applying custom modifications to Android’s EditText and iOS’ UITextField, then call these as Custom Renderers. But we will achieve this using XAML and only code in the shared project. This blog post is about building this edit label custom control in xamarin forms xaml.

An overview of the control

This control is not complicated and the logic behind it is that. It behaves like a text entry when focused and it behaves like a label when it loses focused. So, to implement it in Xamarin Forms XAML, we will use a contentview, leverage Visual States, Gesture Recognizers and add a few bindable properties to make our control.

Here is the source code for this control

Building our custom control in
Xamarin Forms

First, we create a ContentView which will have the atrribute (x:Name=”thisEdiableLabel”), this attribute will be used for referencing in XAML.

We then add a bunch of bindable properties which will be used to customize our control. The most important property here is the “IsFocusedMode” Property, which we will use to play with the views contained in the ContentView.

Initially, our control will need to display already available information. So, the content view’s primary content is a label to display this information. This ContentView will switch to edit mode once the Label gets tapped as shown below.

When tapped, the IsFocusedMode property will be set to true and this will activate the ContentView’s trigger to switch from the label to the entry.

To detect when the user has finished editing and leaves the entry, we will use the Focus Visual State of the Entry. When this visual state is set to false, we launch a Trigger on the ContentView.

Here is the XAML code for this content view.

Let’s add finishing touches. At this stage, the Entry when focused, does not always display the keyboard. The cursor is at the beginning of the text too. These can be corrected by setting a few properties when the FocusMode bindable property changes. In our case, the name of the method in charge of this is called : “OnIsFocusedModePropertyChanged”. This is done as shown below.

Demo

Edit Label Custom Control In Xamarin.Forms demo
Edit Label Custom Control In Xamarin.Forms demo

Conclusion

Building custom controls entirely with XAML and C# in the shared project only is easy and fast. Though it might not always be the best when it comes to performance. Here is a similar blog post about building a
SnackBar in Xamarin Forms with XAML. With this, we built our Entire edit label custom control in Xamarin Forms XAML. This required a bit of code behind to mage states and properties. As I said earlier, this could be achieved using custom renderers, but this approach allow’s saves us per platform modification of the control, though it might not be the best when it comes to performance.

References

https://docs.microsoft.com/fr-fr/xamarin/xamarin-forms/app-fundamentals/gestures/tap
https://docs.microsoft.com/fr-fr/xamarin/xamarin-forms/app-fundamentals/triggers
https://docs.microsoft.com/fr-fr/dotnet/api/xamarin.forms.visualelement.isfocused?view=xamarin-forms

If you find this article useful, please follow me on Twitter,  Github, Linkedin, or like my Facebook page to stay updated.
Follow me on social media and stay updated Follow me on social media and stay updated

9 comments

  1. Nicolas Krier

    Reply

    IMHO, you should avoid x:Name such as this, that etc. Prefer to use the name of the file itself : it will reduce the chance of broken binding.

    For instance, let’s say your page has a x:Name set to “this”. You have an external ContentView which has its root x:Name set with “this” too. Now you add this ContentView in your page without using a x:Name ( . You might assume it will catch the Page but surpriiiise !!! You point at the contentView root element of “this”.

    That’s why I tend to use a meaningful name to avoid any weird error I won’t see coming.

    • Damien Doumer

      Reply

      Yeah, Good observation. I refactored the source code and the blog post. Thanks,

      • Nicolas Krier

        Reply

        Almost there 😀 yout typed thisEdiableLabel instead of thisEditableLabel 😉
        Anyway, nice post !

  2. VeNuSs

    Reply

    In the code behind, it complains that it cannot find MainEntry.

    • VeNuSs

      Reply

      I fixed that problem but now I have got another issue (tested on UWP)
      When I click on the label, it won’t let me type anything and instead it will just focus on another Entry on the page.

      • Damien Doumer

        Reply

        Hi, I built the sample on Android and iOS only. I’ll try it on UWP to check the issue.

        • VeNuSs

          Reply

          I confirm it works on UWP too I was doing something wrong before

          • Damien Doumer

            Ok, its awesome if it works. Thanks for going through this article, If you added the UWP project, though not required you could please contribute it to the original repository on Github in such a way that anyone willing to test the demo on UWP will have access to it.

  3. sessizciglik

    Reply

    this implementation is faulty. once you go on Focusmode and press enter or save button on Android, it will thrown exception because Entry will be disposed by the datatrigger. you cannot access a control created by another datatrigger from the datatrigger. Exact exception will be

    System.ObjectDisposedException: ‘Cannot access a disposed object.
    Object name: ‘Xamarin.Forms.Platform.Android.FormsEditText’.’

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.