How to display data on UI by calling API in Xamarin

拥有回忆 提交于 2020-01-03 18:00:35

问题


I am kinda new to Xamarin and developing an iOS app, I need to call an API and bind the response data to view have used MVVM pattern.

Here is my ViewModel Code:

public class PersonalDetailModel : BaseViewModel
{
    private PersonalDetails personalDetails { get; set; }
    public Command LoadCommand;

    public PersonalDetailModel()
    {
        LoadCommand = new Command(async () => await GetPersonalDetais());

    }
    public String City
    {
        get
        {
            return personalDetails.city;
        }
        set
        {
            personalDetails.city = value;
        }
    }
    public string Phone
    {
        get { return personalDetails.phone; }
        set
        {
            personalDetails.phone = value;

        }
    }
    public string Email
    {
        get { return personalDetails.email; }
        set
        {
            personalDetails.email = value;

        }
    }

    public async Task<PersonalDetails> GetPersonalDetais()
    {
        var ApiRequest = RestService.For<IUserService>(Constants.BaseUrl);

        PersonalDetailsResponse ApiResponse = await ApiRequest.showProfile(Constants.token);

        PersonalDetailsResponse response = ApiResponse;

        this.personalDetails = response.result;
        personalDetails = new PersonalDetails
        {
            city = personalDetails.city,
            phone = personalDetails.phone,
            email = personalDetails.email
        };

        return this.personalDetails;
    }


}

In GetPersonalDetais() I am getting the values from API in debug process but I am not able to bind that value in UI.

XML Code:

<?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="BarberCustomer.Views.PersonalDetails"
             >
    <ContentPage.Content>
        <StackLayout Orientation="Vertical" Padding="4,5" BackgroundColor="#efeff4" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
            <Frame HasShadow="True" Padding="8,5,8,12" CornerRadius="2"  Margin="1,1,0,0" HorizontalOptions="FillAndExpand" 
                   VerticalOptions="Start">
                <StackLayout Orientation="Vertical" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
                    <Label Text="Personal Details" HorizontalOptions="Start" VerticalOptions="FillAndExpand" LineBreakMode="WordWrap" FontSize="12" TextColor="#ad0e0e">
                        <Label.FontFamily>
                            <OnPlatform x:TypeArguments="x:String">
                                <OnPlatform.Android>SFProDisplay-Bold.ttf#SF-Pro-Display-Bold</OnPlatform.Android>
                                <OnPlatform.iOS>SFProDisplay-Bold</OnPlatform.iOS>
                            </OnPlatform>
                        </Label.FontFamily>
                    </Label>
                    <StackLayout Margin="0,1,0,1" HorizontalOptions="FillAndExpand" HeightRequest="1" BackgroundColor="#efeff4" VerticalOptions="EndAndExpand" Padding="0">
                    </StackLayout>
                    <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="Center">
                        <Image Source="location.png" WidthRequest="8" HeightRequest="11" VerticalOptions="Center" Aspect="AspectFit" ></Image>
                        <Label Text="{Binding City}" Margin="4,0,0,0"
                               HorizontalOptions="Start" VerticalOptions="FillAndExpand" LineBreakMode="WordWrap" FontSize="9" TextColor="#253045">
                            <Label.FontFamily>
                                <OnPlatform x:TypeArguments="x:String">
                                    <OnPlatform.Android>SFProDisplay-Medium.ttf#SFProDisplay-Medium</OnPlatform.Android>
                                    <OnPlatform.iOS>SFProDisplay-Medium</OnPlatform.iOS>
                                </OnPlatform>
                            </Label.FontFamily>
                        </Label>

                    </StackLayout>

                    <StackLayout HorizontalOptions="FillAndExpand" HeightRequest="1" BackgroundColor="#eeeeee" VerticalOptions="EndAndExpand" Padding="0" Margin="17,1,0,1">

                    </StackLayout>
                    <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="Center">
                        <Image Source="phone.png" WidthRequest="8" HeightRequest="11" VerticalOptions="Center" Aspect="AspectFit" ></Image>
                        <Label Text="{Binding Phone}" Margin="4,0,0,0"
                               HorizontalOptions="Start" VerticalOptions="FillAndExpand" LineBreakMode="WordWrap" FontSize="9" TextColor="#253045">
                            <Label.FontFamily>
                                <OnPlatform x:TypeArguments="x:String">
                                    <OnPlatform.Android>SFProDisplay-Medium.ttf#SFProDisplay-Medium</OnPlatform.Android>
                                    <OnPlatform.iOS>SFProDisplay-Medium</OnPlatform.iOS>
                                </OnPlatform>
                            </Label.FontFamily>
                        </Label>
                    </StackLayout>
                    <StackLayout HorizontalOptions="FillAndExpand" HeightRequest="1" BackgroundColor="#eeeeee" VerticalOptions="EndAndExpand" Padding="0" Margin="17,1,0,1">

                    </StackLayout>
                    <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="Center">
                        <Image Source="mail.png" WidthRequest="11" HeightRequest="12" VerticalOptions="Center" Aspect="AspectFit" ></Image>
                        <Label Text="{Binding Email}" Margin="4,0,0,0"
                               HorizontalOptions="Start" VerticalOptions="FillAndExpand" LineBreakMode="WordWrap" FontSize="9" TextColor="#253045">
                            <Label.FontFamily>
                                <OnPlatform x:TypeArguments="x:String">
                                    <OnPlatform.Android>SFProDisplay-Medium.ttf#SFProDisplay-Medium</OnPlatform.Android>
                                    <OnPlatform.iOS>SFProDisplay-Medium</OnPlatform.iOS>
                                </OnPlatform>
                            </Label.FontFamily>
                        </Label>
                    </StackLayout>
                </StackLayout>
            </Frame>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

xml.cs:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PersonalDetails : ContentPage
{
    PersonalDetailModel viewModel;

    public PersonalDetails()
    {
        InitializeComponent();

        viewModel = new PersonalDetailModel();

        BindingContext = viewModel;



    }

    protected async override void OnAppearing()
    {
        base.OnAppearing();
        viewModel.LoadCommand.Execute(null);

    }
}

Every response and suggestions will be appreciated!


回答1:


You should put BindingContext either in the xaml.cs or in the xaml to bind your ViewModel with the View.

There are multiple ways to bind the data to your View.

ViewModel.cs

public class PettyCashListViewModel : BaseNavigationViewModel

Page.Xaml.cs

public partial class PettyCashListPage : ContentPage
{
    protected PettyCashListViewModel ViewModel => BindingContext as PettyCashListViewModel;

or Inside your page constructor

this.BindingContext = ViewModel;

or Inside your page.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:viewModels="clr-namespace:XamarinPOC.ViewModel; assembly=XamarinPOC.ViewModel"
         x:Class="XamarinPOC.Summary"
         Title="Summary List">
     <ContentPage.BindingContext>
        <viewModels:SummaryViewModel/>
     </ContentPage.BindingContext>
     <StackLayout>
        <Label Text="{Binding test}"/>
     </StackLayout>
   </ContentPage>

Reference: Set BindingContext to ViewModel in XAML on Xamarin.Forms




回答2:


I second Selvarathinams answer. Also make sure, your model implements the INotifyPropertyChanged interface.

You should add

public event PropertyChangedEventHandler PropertyChanged;

and

protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }

to your model class (unless it is already implemented in the base class your model derives from). Then in all setters call NotifyPropertyChange("propertyName).

For instance it would be:

public string Email
{
    get { return personalDetails.email; }
    set
    {
        personalDetails.email = value;
        NotifyPropertyChanged("Email");
    }
}

This will ensure that your view gets notified that a model value has changed.

Also try updating your model values in your UI thread. In order to do so, where you handle the result from your async method, do the following:

Xamarin.Forms.Device.BeginInvokeInMainThread( () => {
    model.City = personalDetails.city;
    model.Phone = personalDetails.phone;
    model.Email = personalDetails.email;
}

if that shouldn't work, you might change the method in OnAppearing a bit:

protected async override void OnAppearing()
{
    base.OnAppearing();
    PersonalDetails details = await model.GetPersonalDetais();
    Xamarin.Forms.Device.BeginInvokeInMainThread( () => {
        model.City = personalDetails.city;
        model.Phone = personalDetails.phone;
        model.Email = personalDetails.email;
    }
}

Speaking of, I personally find it a bit strange that the method to retrieve the data is part of your model class. It would implement such a method inside of a static class called DataService, which holds all the methods used to retrieve data and keep the model clean so that it only contains the data needed to be bound to the view.



来源:https://stackoverflow.com/questions/51079625/how-to-display-data-on-ui-by-calling-api-in-xamarin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!