11
votes

I am relatively new to Xamarin forms. I have found out I am unable to change label text from the code behind. Normally I would do myLabel.text = variable. Does this work in Xamarin? If it does why does this code not change the text?

Label_ControlSW.Text = controlSW_Out;
            Label_BLESW.Text = bleSW_Out;
            Label_Mode.Text = mode_Out;

Xaml file

<Label x:Name="Label_ControlSW" Grid.Row="1" Grid.Column="1" HorizontalOptions="Center"  VerticalOptions="Center" FontSize="17" TextColor="White"/>
                <Label x:Name="Label_BLESW" Grid.Row="2" Grid.Column="1" HorizontalOptions="Center"  VerticalOptions="Center" FontSize="17" TextColor="#525252"/>
                <Label x:Name="Label_Mode"  Grid.Row="4" Grid.Column="1" HorizontalOptions="Center"  VerticalOptions="Center" FontSize="17" TextColor="White"/>
5
is textColor & background color same?R15
No they are different coloursBleari
have u tried debugging whether values are there or not in variablesR15
The values are there, the label text is also shown to have changed to the variable. The screen doesn't change.Bleari
Are you doing this while processing something big on the UI/main thread? If so, you may want to wait for it to finish, and then the UI will update.GregorMohorko

5 Answers

18
votes

Does this work in Xamarin?

Yes, it does.

If it does why does this code not change the text?

Because the Label component is not bounded to the variable, it just gets its value when you did Label_ControlSW.Text = controlSW_Out; and no furthermore.

To make it works you have basically two choices:

1. Set the value to the label on every change;

There's no magic here. Just set the values or variables like Ali Heikal's answer suggests, but you must do that every time manually.

2. Bind the page (View) to an Observable object (Model), then the view will listen to every change on your model and react to this (changing it's own Text value, for example).

I guess what you're intending to do is the second one. So you can create a public string property on your page's code-behind and bind the instance of your page to itself. Like this:

XAML

<Label Text="{Binding MyStringProperty}"
       .../>

Code behind

public partial class MyTestPage : ContentPage
{
    private string myStringProperty;
    public string MyStringProperty
    {
        get { return myStringProperty; }
        set 
        {
            myStringProperty = value;
            OnPropertyChanged(nameof(MyStringProperty)); // Notify that there was a change on this property
        }
    }
    
    public MyTestPage()
    {
        InitializeComponents();
        BindingContext = this;

        MyStringProperty = "New label text"; // It will be shown at your label
    }
}

You should take a look at official docs about data bindings and MVVM pattern on XF and if you're starting with Xamarin.Forms, I highly recommend you to follow the official getting started guide that addresses each topic clear and deep enough to learn everything you need.

I hope it helps.

7
votes

Try initializing the Text value in XAML like the following:

<Label x:Name="YourLableName" Text="Initial Label"/>

Then access it in the code behind like the following:

YourLableName.Text = "Desired Name";

or

YourLableName.Text = variable;
3
votes

In order to update the UI, you have to be on the UI thread. You would want to do something like:

 Device.BeginInvokeOnMainThread(() =>
 {
     Label_ControlSW.Text = controlSW_Out;
     Label_BLESW.Text     = bleSW_Out;
     Label_Mode.Text      = mode_Out;
 });

This will solve your problem, but as the others have stated in their answers, the Xamarin way to do this would be using data binding to update the view. The data binding will handle the UI update for you.

0
votes

I faced the same issue. Try to clean and build your project after u make x:Name reference in your view folder. Or you can do Data binding. By using this code

 <Label Text="{Binding MyProperty}" />

in Xaml. And in ViewModel class

public class MyViewModel
{
    public string MyProperty { get; set; } = "My Label Text";
}

And in code behind just mention the ViewModel your using

this.BindingContext = new MyViewModel();

This is the correct approach. So try to use MVVM approach in your future of coding because this is the right approach.

0
votes

There were a few reasons why this didn't work. I changed to the MVVM approach. This still had no effect but it was a better approach as was suggested. When debugging I noticed this line: I/Choreographer(16942): Skipped 31 frames! The application may be doing too much work on its main thread. This was because I was doing too much on the main thread (ble connections) and it was just skipping the UI change. I had to restructure my code to perform more on different threads. Thanks for the help everyone.