3

Last night I spent 5 hours trying to work out how to update a label value in Xamarin Forms but got nowhere.

My xaml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Meditation.HomePage">
<ContentPage.Content>
    <Button Text="{Binding SelectedSound}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" Clicked="OnButtonClicked" />
</ContentPage.Content>

My main page class looks like this:

using System;
using System.Collections.Generic;
using Xamarin.Forms;

namespace Meditation
{
public partial class HomePage : ContentPage
{
    public String SelectedSound { get; set; } 

    public HomePage()
    {
        InitializeComponent();

        this.Title = AppInfo.AppName; 
    }

    protected override void OnAppearing()
    {
        ShowSelectedSound();
        BindingContext = this;
    }

    protected override void OnDisappearing()
    {
        DependencyService.Get<IAudio>().StopAudio();
    }

    // User Actions

    void OnButtonClicked(object sender, EventArgs args)
    {
        Navigation.PushAsync(new SoundSelectionPage());
    }

    // Private

    private void ShowSelectedSound()
    {
        if (Application.Current.Properties.ContainsKey(AppInfo.keySoundSelected))
        {
            SelectedSound = Application.Current.Properties[AppInfo.keySoundSelected] as string;
        }                                      

        else
        {
            this.SelectedSound = "Choose sound";
        }
    }
}
}

The button correctly shows the text as 'Choose sound' when the page first loads. However, when I come back to this page it fails to update the text, when the application.current.properties key value exists.

Anyone know why the label only seems to update when the page first loads and not ongoing. And more importantly can anyone provide the code to get the button text to update after it has initially set?

Charlie S
  • 4,366
  • 6
  • 59
  • 97
  • you're binding to `SelectSoundButtonText` , but your property name is `SelectedSound`. who does it work? – esiprogrammer Jan 20 '17 at 10:47
  • Sorry. That was a typo (updated it in question). The issue is still outstanding. First time the page loads the button text appears but then never updates. – Charlie S Jan 20 '17 at 10:49

1 Answers1

4

You must implement INotifyPropertyChanged in your homepage class to be able to update the page.

public partial class HomePage : ContentPage,  INotifyPropertyChanged
{

        private string selectedSound;
        public string SelectedSound
        {
            get
            {
                return selectedSound;
            } set
            {
                if (selectedSound!=value)
                {
                    selectedSound = value;
                    this.OnPropertyChanged("SelectedSound");
                }
            }
        }

   .....

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

}

but I would recommend to implement MVVM pattern and define a ViewModel instead.

esiprogrammer
  • 1,438
  • 1
  • 17
  • 22
  • Just tried setting the 'x:Name' property for the button in the xaml. Then referred to that name in my code to get the button object in my code. Then updated the text value and it all worked, without needing PropertyChanged code. Is that a valid alternative? – Charlie S Jan 20 '17 at 12:07
  • 2
    you could always change your objects using code-behind. x:name generates a field and you can use it in code behind. but it's not a smart way of implementing . As I said it's highly recommended to use databinding insted. using a pattern like `MVVM` is a plus – esiprogrammer Jan 20 '17 at 12:13
  • Ah ok. Why is MVVM better? – Charlie S Jan 20 '17 at 12:33
  • 1
    [Why MVVM](http://stackoverflow.com/questions/1644453/why-mvvm-and-what-are-its-core-benefits) – esiprogrammer Jan 20 '17 at 12:38
  • Thats really interesting. Thank you very much. I came from Xcode (MVC) background and so it feels like a lot more effort than Im used to but I appreciate the rational for the additional abstraction. – Charlie S Jan 20 '17 at 12:44