0
votes

I am currently working with a static method on my page (It is static because it works with other pages). At the end of this method I foreach the results of a list and give the x:name of my label (that i have created in my XAML page) a new text.

To test to see if it worked I write out the labels text in the log and the correct text indeed gets written out, however the text does not get updated on the app.

The code looks something like this:

public static MyPage currentpage = new MyPage(); 

This is the current page that i am working on. In order to reach the labels x:name I created this code.

And then this is the static method on this page also.

public static async Task loadTheData(string token) //method is static because i send a token from another page
    {
        ...

        foreach (var profileinfo in App.registeredUsers) //this is my list
        {
            currentpage.myXAMLlabel.Text = profileinfo.name; //this is the label where i assign the new text
        }

        System.Diagnostics.Debug.WriteLine(currentpage.myXAMLlabel.Text); //the correct text gets written out in the log but the text does not get updated "visually" on the app
    }

So as I mentioned above, I get the correct text in the log but the text of the label does not get updated "visually" on the app screen.

I call the static method firstly from the specific iOS/Android folders:

 App.SuccessfulLoginAction.Invoke();

And on my app-page I have the following method:

  public static Action SuccessfulLoginAction
    {
        get
        {
            return new Action(async () =>
            {
                await MyPage.loadTheData(token);
            });

        }
    }

I could move the SuccessfulLoginAction to MyPage instead of having it on the App page. But the method has to still be static i suppose (?) in order for the iOS code to reach the Action.

How can I adjust my code to solve this problem?

2
This is the same for any GUI - you shouldn't block it. And your foreach() is very blocking. - Henk Holterman
The method has to be static in order for me to reach this from other pages. In order for me to talk to my page from this static method i created this code snippet: public static MyPage currentpage = new MyPage(); but it is not working correctly. - Martman
The static is just ugly and a bad idea but not the core problem here. - Henk Holterman
Yeah I don't like working with static methods either. But I assume I need it in order to reach this method from other pages right? - Martman
There are always other (and better) ways, but the real issue is that forms/pages shouldn't know each other at all. This is a sign of biz logic in the UI. Study on MVVM. - Henk Holterman

2 Answers

1
votes

If I read your question correctly, you are adding the public static MyPage currentpage = new MyPage(); in the MyPage class?

If that's the case, your instance of MyPage in the currentPage variable, won't be the same instance that you see on the screen. The Debug message will show the instance that is not on screen. You could implement what you want with the singleton pattern.

Get rid of the statics by using the MessagingCenter

Or better yet, to get rid of the statics, make use of the MessagingCenter pub/sub mechanism or any other MVVM equivalent. Example for the MessagingCenter:

You can use the App class as the sender from your platform specific projects. Like this:

MessagingCenter.Send<App>((App)Xamarin.Forms.Application.Cur‌​rent, "myEvent") 

Subscribe in your App class:

MessagingCenter.Subscribe<App>(this, "myEvent", ...)

If you want to subscribe in your page:

MessagingCenter.Subscribe<App>((App)Application.Current, "myevent", ...)

See the docs for more information.

Updating UI elements on the right thread

You should also make sure to update UI elements on the Main Thread (which you probably won't be on because you are using async/await). As @SushiHangover mentioned in his answer by using Device.BeginInvokeOnMainThread:

Device.BeginInvokeOnMainThread(() =>
{
     currentpage.myXAMLlabel.Text = profileinfo.name;
});
1
votes

Make sure you are updating any UI elements on the UI/main thread, i.e.:

Device.BeginInvokeOnMainThread(() =>
{
    currentpage.myXAMLlabel.Text = profileinfo.name; //this is the label where i assign the new text
});