4

我是 MvvmCross 和 Android 开发的新手。我需要在我的视图模型中调用 POST 数据到 JSON Web 服务。然后我需要在我的 UI 中显示 Web 服务的结果。我的视图模型的要点如下所示:

public class MyViewModel : MvxViewModel
{
  public override void Start()
  {
    base.Start();
  }

  public event EventHandler<EventArgs> Service_Finished;
  public void CallService()
  {
    string url = GetServiceUrl();

    WebRequest serviceRequest = HttpWebRequest.Create(url);
    serviceRequest.Method = "POST";
    serviceRequest.ContentType = "application/json";
    serviceRequest.BeginGetRequestStream(new AsyncCallback(ServiceBeginGetRequestStreamCallback), serviceRequest);
  }

  private void ServiceBeginGetRequestStreamCallback(IAsyncResult ar)
  {
    string json = GetJson();

    HttpWebRequest myWebRequest = (HttpWebRequest)(ar.AsyncState);
    using (Stream postStream = myWebRequest.EndGetRequestStream(ar))
    {
      byte[] byteArray = Encoding.UTF8.GetBytes(json);
      postStream.Write(byteArray, 0, byteArray.Length);
    }
    myWebRequest.BeginGetResponse(new AsyncCallback(Service_Completed), myWebRequest);
  }

  private void Service_Completed(IAsyncResult result)
  {
    if (Service_Finished != null)
      Service_Finished(this, new EventArgs());
  }
}

在我的视图 (UI) 代码中,我为事件添加了一个事件处理程序Service_Finished。我注意到我可以从CallService我的视图模型中的 " " 方法成功地抛出事件。但是,如果我尝试Service_Finished从部分ServiceBeginGetRequestStreamCallbackService_Completed部分中触发,则永远不会在 UI 中触发该事件。

由于视图模型位于可移植类库中,我不知道如何调试它。此时我知道 CallService 已成功调用。但是,我不知道我在哪里进入ServiceBeginGetRequestStreamCallback,如果我什至到达Service_Completed

我从我的 Windows Phone 开发经验中知道,我需要检查我是否在 UI 线程上,如果不是,我必须做一些 Deployment.stuff。但是,使用 MvvmCross 方法,我不确定 a) 是否必须这样做,b) 是否可以选择,因为视图模型应该适用于 Android 和 iOS。无论如何,必须有一种方法来 a) 从视图模型调用 Web 服务 b) 将消息发送回视图以便更新 UI。不幸的是,我似乎无法弄清楚。有人(slodge :))可以告诉我我做错了什么吗?

谢谢

4

1 回答 1

9

通常,我将这种 WebService 调用放在 Model 而不是 ViewModel 中——它使 ViewModel 和 WebService 客户端代码更易于重用。

一些简单的例子如下:

我从我的 Windows Phone 开发经验中知道,我需要检查我是否在 UI 线程上,如果不是,我必须做一些 Deployment.stuff。但是,使用 MvvmCross 方法,我不确定 a) 如果我必须这样做并且

是的,来自 ViewModel->View 的所有通信都应该在 UI 线程上。

b)如果这甚至是一个选项,因为视图模型应该适用于 Android 和 iOS。

MvvmCross 提供了一个接口,允许您将执行编组到 UI 线程上。在 ViewModel 中,这很容易通过调用InvokeOnMainThread(() => { /* your code */ })

在幕后,MvvmCross 也会将所有RaisePropertyChanged执行编组到 UI 线程。注意- 虽然ObservableCollection更新不会自动编组 - 这是因为ObservableCollection它是一个存在于 MvvmCross 之外的类。

无论如何,必须有一种方法来 a) 从视图模型调用 Web 服务,并且

见样品(上)

b) 将消息发送回视图,以便更新 UI。

一般来说,您不应该通过事件发送这些类型的消息。

相反,您应该:

  • 更新 ViewModel 属性
  • (偶尔)通过 Messenger 发送消息
于 2013-04-22T08:41:42.833 回答