使用mvvm绑定xamarin上的数据集合

时间:2017-12-18 13:27:59

标签: c# xamarin mvvm xamarin.forms models

所以我开始学习xamarin并尝试从视图到模型的数据绑定的不同方法。我正在使用post请求从服务中检索数据,在我获取数据后,我无法将它们绑定到视图。经过大量的研究,我找到了一些有趣的解决方案,并尝试了不同的方法。 这是我迄今取得的成就: 我的观点:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Ideas.Pages.IdeasSinglePage"
         xmlns:vm="clr-namespace:Ideas.ViewModel;assembly=Ideas"
          Title="My idea">

<ContentPage.BindingContext>
    <vm:IdeasViewModel/>
</ContentPage.BindingContext>

<StackLayout>
    <Button Command="{Binding GetIdeasCommand}"
            Text="Bileta Ime"
            TextColor="White"
            FontSize="15"
            BackgroundColor="#29abe2"/>
    <Label Text="test"></Label>

    <ListView ItemsSource="{Binding Ideas}"
              HasUnevenRows="True">

        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Padding="20, 10">
                        <Label  Text="{Binding IdeasName}"
                                 FontSize="16"
                               TextColor="RoyalBlue"/>

                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</StackLayout>

这是我的viewmodel

public class IdeasViewModel : INotifyPropertyChanged
{
    ApiServices _apiServices = new ApiServices();
    public List<Ideas> Ideas
    {
        get { return Ideas; }
        set
        {
            Ideas= value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public ICommand GetIdeasCommand
    {
        get
        {
            return new Command(async () =>
            {
                Ideas= await _apiServices.GetIdeasAsync();
            });
        }
    }


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

}

这是我的服务:

public async Task<List<Ideas>> GetIdeasAsync()
    {
        ListIdeasDetails ideas= null;
        try { 
            var client = new HttpClient();
            client.DefaultRequestHeaders.Add("parameter", "parameter");
            client.DefaultRequestHeaders.Add("parameter", parameter);

            HttpContent content = new StringContent("");
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            var response = await client.PostAsync("https://heregoes/themethod", content);
            response.EnsureSuccessStatusCode();
            string json = await response.Content.ReadAsStringAsync();
            ideas= JsonConvert.DeserializeObject<ListIdeasDetails>(json);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message.ToString());
        }
        return ideas.Ideas;
    }
}

这是我的两个模特:

public class Ideas
{

    public string IdeasID  { get; set; }

    public string IdeasName  { get; set; }
 }


class ListIdeasDetails
{
    public List<Ideas> Ideas{ get; set; }
    public string ExceptionMessage { get; set; }
    public bool HasException { get; set; }

}

我真的很感激一些帮助!谢谢!

1 个答案:

答案 0 :(得分:2)

好像您的property definition

有问题
 public List<Ideas> Ideas
 {
    get { return Ideas; }
    set
    {
        Ideas= value; // Endless loop
        OnPropertyChanged();
    }
 }

以这种方式添加支持字段:

List<Ideas> _ideas;
public List<Ideas> Ideas
{
    get { return _ideas; }
    set
    {
        if(value == _ideas) return;
        _ideas = value;
        OnPropertyChanged();
    }
}

我建议使用Fody.PropertyChanged以减少与INotifyPropertyChanged相关的样板代码量。使用Fody,您的ViewModel将如下所示:

public class IdeasViewModel : INotifyPropertyChanged
{
    ApiServices _apiServices = new ApiServices();
    public List<Ideas> Ideas { get;set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public ICommand GetIdeasCommand
    {
        get
        {
            return new Command(async () =>
            {
                Ideas= await _apiServices.GetIdeasAsync();
            });
        }
    }
}

P.S。:除了你的主要问题,我想指出接下来在你的代码中看起来不太好的东西。

  1. 使用POST从WEB下载数据。
  2. 班级名称'ApiServices'。
  3. 如果您需要通过评论获得进一步的帮助,可以通知我。