Search code examples
xamarin.formsmvvmlabel

How to update label in Xamarin Forms


Beginner here.

I'm trying to get the exact time, when this operation was executed successfully and print it on label. The problem is that when I click the button, the label doesn't update the text.

namespace HGB.Droid.Helpers
{
    public class CallServiceHelper : ICallServiceHelper
    {
        IContactsHelper contactsHelper = DependencyService.Get<IContactsHelper>();
        List<Repository> ObjContactList = new List<Repository>();

        LabelModel labelModel = new LabelModel();

        Context context = Android.App.Application.Context;
        HttpClient client = new HttpClient();

        public async Task UpdatePhonebook()
        {
            if (NetworkCheck.IsInternet())
            {
                var response = await client.GetAsync("http://mmmmmmmmmmm.aspx");
                if (response.IsSuccessStatusCode)
                {
                    string contactsJson = await response.Content.ReadAsStringAsync();
                    var list = JsonConvert.DeserializeObject<List<Repository>>(contactsJson);

                    contactsHelper.DeleteContact();
                    ObjContactList = list;
                    foreach (Repository obj in ObjContactList)
                    {
                        contactsHelper.CreateContacts(obj.name, obj.phone);
                    }
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        labelModel.UpdateLabelValue.Execute(DateTime.Now.ToString());
                    });
                }
            }
            else
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    Toast.MakeText(context, "Error", ToastLength.Long).Show();
                });
                
            }
        }

I'm calling this function on UI button

public partial class MainPage : ContentPage
{
    ICallServiceHelper callServiceHelper = DependencyService.Get<ICallServiceHelper>();

    public MainPage()
    {
        InitializeComponent();
    }

    private async void updateContactsBtn_Clicked(object sender, EventArgs e)
    {
        await callServiceHelper.UpdatePhonebook();
    }
}

This is my ViewModel

 public class LabelModel : BindableObject
{
    string dateValue = "Date Value";

    public LabelModel()
    {
        UpdateLabelValue = new Command<string>(UpdateLabel);
    }

    public ICommand UpdateLabelValue { get; }

    public string DateDisplay
    {
        get => dateValue;
        set
        {
            dateValue = value;
            OnPropertyChanged(nameof(DateDisplay));
        }
    }

    void UpdateLabel(string newLabel)
    {
        DateDisplay = newLabel;
    }
}

And this is my Xaml file

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         xmlns:local="clr-namespace:HGB.ViewModel"
         x:Class="HGB.MainPage">

<ContentPage.BindingContext>
    <local:LabelModel/>
</ContentPage.BindingContext>

<StackLayout HorizontalOptions="Center" VerticalOptions="Center" Spacing="10">
    <Button
        Text="Update Phonebook"
        x:Name="updateContactsBtn"
        Clicked="updateContactsBtn_Clicked"
        />
    <Label
        VerticalOptions="Center"
        HorizontalOptions="Center"
        Text="{Binding DateDisplay}"
        />
</StackLayout>

Solution

  • I'm using the Helper method in my Foreground Service class, where it gets called every 24 hours. What I'm trying to achieve is print the exact time, when the phonebook was successfully updated and print that date to my label.

    For your problem, a simple method is to use MessagingCenter just as Jason mentioned.

    You can send message in your CallServiceHelper and subscribe to this message in your ViewModel(LabelModel.cs).

    Please refer to the following code:

    1.In the constructor of your ViewMode(LabelModel.cs),subscribe to this message:

       public LabelModel()
        {
         MessagingCenter.Subscribe<object, string>(this, "time", (sender, args) =>
        {
            System.Diagnostics.Debug.WriteLine("received time is: "+ args);
    
            DateDisplay  = args;
        });
        }
    

    2.In your CallServiceHelper , public your message:

    MessagingCenter.Send<object, string>(this, "time", "2022-4-8");