Xamarin Forms entry control does not show bound text

799 Views Asked by At

In have a project where I have three Entry controls on the screen. They are all bound to backing properties that all have text in them. When I run the app, only the entry control that has focus will show its text. The other entry controls will not show their text until they receive focus. I have report the problem to Microsoft. I was just curious if anyone else had encountered the problem and found a work around until it is fixed. ( I am running as a UWP project)

Steps to Replicate. Create a new Xamarin forms app called EntryControlError. Please include a UWP project in the solution.

Once the project is created, open the MainPage.xaml file and replace all the contents with the XAML below:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             BackgroundColor="#D0E1F9"
             x:Class="EntryControlError.MainPage">

    <ContentPage.Content>
        <StackLayout x:Name="slFullPage" Orientation="Vertical" HorizontalOptions="Fill" VerticalOptions="FillAndExpand" Margin="0,32,0,0" Padding="0,0,0,0">
            <ScrollView HorizontalOptions="Fill" VerticalOptions="FillAndExpand">
                <StackLayout Orientation="Vertical" HorizontalOptions="Fill" VerticalOptions="FillAndExpand">
                    <StackLayout x:Name="slTextHeader" Orientation="Vertical" HorizontalOptions="Center" VerticalOptions="Start">
                        <Label x:Name="lblTextHeaderInfo" Text="Enter Text - Max Three Lines" HorizontalOptions="Center" VerticalOptions="Start"
                               TextColor="#283655" FontAttributes="Bold" FontSize="Small" />

                        <Entry x:Name="txtHeaderText1" HorizontalOptions="Fill" VerticalOptions="Start" Text="{Binding KioskHeaderText1, Mode=TwoWay}" 
                               TextColor="#283655" HorizontalTextAlignment="Center" FontAttributes="Bold" FontSize="Medium"  />
                        <Entry x:Name="txtHeaderText2" HorizontalOptions="Fill" VerticalOptions="Start" Text="{Binding KioskHeaderText2, Mode=TwoWay}" 
                               TextColor="#283655" HorizontalTextAlignment="Center" Margin="0,-8,0,0" FontAttributes="Bold" FontSize="Medium" />
                        <Entry x:Name="txtHeaderText3" HorizontalOptions="Fill" VerticalOptions="Start" Text="{Binding KioskHeaderText3, Mode=TwoWay}" 
                               TextColor="#283655" HorizontalTextAlignment="Center" Margin="0,-8,0,0" FontAttributes="Bold" FontSize="Medium" />
                    </StackLayout>
                </StackLayout>
            </ScrollView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Replace everything in the MainPage.xaml.cs file with the following:

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Xamarin.Forms;

namespace EntryControlError
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _KioskHeaderText1;
        public string KioskHeaderText1
        {
            get { return _KioskHeaderText1; }
            set
            {
                _KioskHeaderText1 = value;
                OnPropertyChanged();
            }
        }
        private string _KioskHeaderText2;
        public string KioskHeaderText2
        {
            get { return _KioskHeaderText2; }
            set
            {
                _KioskHeaderText2 = value;
                OnPropertyChanged();
            }
        }
        private string _KioskHeaderText3;
        public string KioskHeaderText3
        {
            get { return _KioskHeaderText3; }
            set
            {
                _KioskHeaderText3 = value;
                OnPropertyChanged();
            }
        }

        public MainPage()
        {
            try
            {

                InitializeComponent();
                NavigationPage.SetHasNavigationBar(this, false);
                NavigationPage.SetHasBackButton(this, false);

                KioskHeaderText1 = "Line 1 Text";
                KioskHeaderText2 = "Line 2 Text";
                KioskHeaderText3 = "Line 3 Text";

                txtHeaderText1.BindingContext = this;
                txtHeaderText2.BindingContext = this;
                txtHeaderText3.BindingContext = this;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error: " + ex.Message);
            }
        }

        /// <summary>
        /// Manual Notification to subscribers that a property has changed. 
        /// </summary>

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

    }

}

Run the app and the screen will look like:

enter image description here

If you click into the second or third entry control without entering anything, their bound text will automatically appear.

2

There are 2 best solutions below

0
George M Ceaser Jr On BEST ANSWER

It appears the later releases of Xamarin Forms have fixed the issues. If you are still encountering the challenge, ensure your Xamarin Forms is up to date.

8
Cherry Bu - MSFT On

According to Jason's opinion, you don't need to set each entry BindingContext, just set the current Page BindingContext.

Then you create three properties, don't implement INotifyPropertyChanged interface, so when these properties changed, you can not update UI.

I modify your code about binding part, you can take a look:

 public partial class Page6 : ContentPage, INotifyPropertyChanged
{

    private string _KioskHeaderText1;
    public string KioskHeaderText1
    {
        get { return _KioskHeaderText1; }
        set
        {
            _KioskHeaderText1 = value;
            RaisePropertyChanged("KioskHeaderText1");
        }
    }
    private string _KioskHeaderText2;
    public string KioskHeaderText2
    {
        get { return _KioskHeaderText2; }
        set
        {
            _KioskHeaderText2 = value;
            RaisePropertyChanged("KioskHeaderText2");
        }
    }
    private string _KioskHeaderText3;
    public string KioskHeaderText3
    {
        get { return _KioskHeaderText3; }
        set
        {
            _KioskHeaderText3 = value;
            RaisePropertyChanged("KioskHeaderText3");
        }
    }
    public Page6()
    {
        InitializeComponent();

        KioskHeaderText1 = "Line 1 Text";
        KioskHeaderText2 = "Line 2 Text";
        KioskHeaderText3 = "Line 3 Text";


        this.BindingContext = this;
    }

    public event PropertyChangedEventHandler PropertyChanged;     
    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }


}

Finally, because you have used binding for Entry, so I don't suggest you change Entry text directly, you can change KioskHeaderText1 ,KioskHeaderText2 ,KioskHeaderText3 properties to change Entry text.