在ViewModel中检索REST数据

时间:2015-10-01 17:19:28

标签: c# wpf mvvm

我尝试创建一个使用MVVM与REST API集成的应用程序。我正在努力从我的View Model中的端点提取数据并将数据绑定到我的View。这是我迄今为止的测试。

查看模型

class MainViewModel : INotifyPropertyChanged
{
    public MainViewModel()
    {

    }

    private List<Schedule> schedules;
    public List<Schedule> Schedules
    {
        get
        {
            if (schedules == null)
                GetData();
            return schedules;
        }
        set
        {
            schedules = value;
            RaisePropertyChanged("Schedules");
        }
    }
    private string homeTeam;
    public string HomeTeam
    {
        get
        {
            return homeTeam;
        }
        set
        {
            homeTeam = value;
            RaisePropertyChanged("HomeTeam");
        }
    }
    private async void GetData()
    {
        // Simulate pulling data from api
        string response;
        StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///DesignData/GetLive.json"));
        using (StreamReader sRead = new StreamReader(await file.OpenStreamForReadAsync()))
            response = await sRead.ReadToEndAsync();

        // Deserialize data to class
        LiveStreamModel liveGames = JsonConvert.DeserializeObject<LiveStreamModel>(response);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

查看

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView ItemsSource="{Binding Schedules}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding HomeTeam}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

模型

class LiveStreamModel
{
    public string Status { get; set; }
    public string msg { get; set; }
    public List<Schedule> schedule { get; set; }
    public IEnumerator<Schedule> GetEnumerator()
    {
        return this.schedule.GetEnumerator();
    }
}
public class Schedule
{
    public int id { get; set; }
    public string @event { get; set; }
    public string homeTeam { get; set; }
    public int homeScore { get; set; }
    public string awayTeam { get; set; }
    public int awayScore { get; set; }
    public string startTime { get; set; }
    public int period { get; set; }
    public int isHd { get; set; }
    public int isPlaying { get; set; }
    public int isWMV { get; set; }
    public int isFlash { get; set; }
    public int isiStream { get; set; }
    public string feedType { get; set; }
    public string srcUrl { get; set; }
    public string hdUrl { get; set; }
    public string sdUrl { get; set; }
    public string trueLiveSD { get; set; }
    public string trueLiveHD { get; set; }
}

通常在过去,我会在我的View代码中调用GetData()方法,然后在那里为ListView设置ItemSource。我怎样才能正常工作?

1 个答案:

答案 0 :(得分:0)

在视图模型中设置属性:

// Deserialize data to class
LiveStreamModel liveGames = JsonConvert.DeserializeObject<LiveStreamModel>(response);
Schedules = liveGames.schedule;

并确保将数据模板中的文本块数据绑定到Schedule类型的属性(数据绑定以列表项为目标,而不是视图模型,因此{{1视图模型的属性未使用):

HomeTeam

顺便说一下。 <ListView ItemsSource="{Binding Schedules}"> <ListView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding homeTeam}" /> </DataTemplate> </ListView.ItemTemplate> </ListView> 的getter不应该像这样调用Schedules并期望初始化GetData。相反,明确地设置字段然后您可以异步调用schedules以开始加载数据(然后更新属性):

GetData

更好的方法是明确地在其他地方调用get { if (schedules == null) { schedules = new List<Schedule>(); GetData(); } return schedules; } ,所以你明确地设置视图模型,并且没有在(不受监视的)背景中的某个地方运行异步进程