1
votes

I have a Xamarin Forms app that shows a picture that is bound to a class (RandomChallenge). The class is generated in the view model and assigned. The class has a Uri property which we want to bind to an image in the view.

When the app loads it doesn't show any picture, even though RandomChallenge is not null. If I make a change to the UI code whilst debugging and save it, when the debugger reloads the image is visible. Its as if the RandomChallenge class gets populated after the page renders? If I was to put a break point on the line RandomChallenge = await ChallengeDataStore.GetRandomChallenge(); RandomChallenge is populated.

ViewModel

public class MainMenuViewModel : BaseViewModel
{
    public ICommand OpenWebCommand { get; }

    public IdentificationChallenge RandomChallenge { get; set; }

    public Command LoadChallengeCommand { get; set; }

    public MainMenuViewModel()
    {
        Title = "Main Menu";

        LoadChallengeCommand = new Command(async () => await ExecuteLoadChallengeCommand());

        this.LoadChallengeCommand.Execute(null);
    }

    async Task ExecuteLoadChallengeCommand()
    {
        if (IsBusy)
            return;

        try
        {
            RandomChallenge = await ChallengeDataStore.GetRandomChallenge();

            Debug.WriteLine("TEst");
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        finally
        {
            IsBusy = false;
        }
    }
}

UI

<?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"
 xmlns:microcharts="clr-namespace:Microcharts.Forms;assembly=Microcharts.Forms"
         mc:Ignorable="d"
         x:Class="HOG.MobileApp.Views.MainMenuPage"
         xmlns:vm="clr-namespace:HOG.MobileApp.ViewModels"
          xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"    
         Title="{Binding Title}">





<ContentPage.Resources>
    <ResourceDictionary>
        <Color x:Key="Primary">#72a230</Color>
        <Color x:Key="Accent">#72a230</Color>
        <Color x:Key="LightTextColor">#72a230</Color>
    </ResourceDictionary>
</ContentPage.Resources>

<ContentPage.ToolbarItems>
    <ToolbarItem Text="Help" />
</ContentPage.ToolbarItems>

<ContentPage.Content>
    <Image Source="{ Binding RandomChallenge.Picture }" HeightRequest="450" WidthRequest="450" />
</ContentPage.Content>

1
RandomChallenge's setter does not call PropertyChangedJason
@Jason have you an example of how to implement this?dynmatt
there are thousands of existing posts, articles, blogs, tutorials, etc on how to use INotifyPropertyChangedJason
I recommend that you use a framework to help you with the MVVM standard, such as Prism. It will be useful to use the RaisePropertyChanged () method.Filipe Piletti Plucenio

1 Answers

1
votes

So the answer was to call OnPropertyChanged when RandomChallenge is assigned. The ViewModel did implement INotifyPropertyChanged on its parent class.

async Task ExecuteLoadChallengeCommand()
    {
        if (IsBusy)
            return;

        try
        {
            RandomChallenge = await ChallengeDataStore.GetRandomChallenge();

            OnPropertyChanged("RandomChallenge");

            Debug.WriteLine("TEst");
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        finally
        {
            IsBusy = false;
        }
    }