我对使用C#为WP7进行开发非常陌生。我正在尝试编写一个简单的应用程序,它将从textBox1获取url,并在按下按钮1时用该页面的源代码更新textBlock1中的文本。
我一直关注的部分是如何将DownloadStringCallback2中的Result传递回LoadSiteContent函数,以便将其作为变量sourceCode返回。
代码如下:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace TestApp1
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
string url = textBox1.Text;
string sourceCode = LoadSiteContent(url);
textBlock1.Text = sourceCode;
}
/// <summary>
/// method for retrieving information from a specified URL
/// </summary>
/// <param name="url">url to retrieve data from</param>
/// <returns>source code of URL</returns>
public string LoadSiteContent(string url)
{
//create a new WebClient object
WebClient client = new WebClient();
//create a byte array for holding the returned data
string sourceCode = "Fail";
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadStringCallback2);
client.DownloadStringAsync(new Uri(url));
//use the UTF8Encoding object to convert the byte
//array into a string
//UTF8Encoding utf = new UTF8Encoding();
//return the converted string
//return utf.GetString(html, 0, html.Length);
return sourceCode;
}
private static void DownloadStringCallback2(Object sender, DownloadStringCompletedEventArgs e)
{
// If the request was not canceled and did not throw
// an exception, display the resource.
if (!e.Cancelled && e.Error == null)
{
string textString = (string)e.Result;
}
}
}
}
您不能随心所欲,因为WP7(silverlight)中的所有web请求都是异步的。这意味着代码在下载网页时不会停止,并在同一行和函数中完成后继续,而是创建一个新线程,下载文件并调用回调函数。
您必须继续使用回调函数(在您的情况下为DownloadStringCallback2)。在该函数中,您必须将源代码(e.Result)放入文本框中。
我可以补充一点,如果你遇到跨线程异常,或者如果你想在执行任务时保持UI的可用性,你可以使用以下命令:
Dispatcher.BeginInvoke(new Action (() => LoadContent("http://www.google.com")));
这个命令修复了跨线程异常(如果我没记错的话),并在不同于UI线程的线程上执行代码,从而维护了稳定的UI。
EDIT我认为您的代码应该是这样的:
private void button1_Click(object sender, RoutedEventArgs e)
{
string url = textBox1.Text;
LoadSiteContent(url);
}
public string LoadSiteContent(string url)
{
//create a new WebClient object
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadStringCallback2);
client.DownloadStringAsync(new Uri(url));
}
private static void DownloadStringCallback2(Object sender, DownloadStringCompletedEventArgs e)
{
// If the request was not canceled and did not throw
// an exception, display the resource.
if (!e.Cancelled && e.Error == null)
{
textBlock1.Text = (string)e.Result;
//If you get the cross-thread exception then use the following line instead of the above
//Dispatcher.BeginInvoke(new Action (() => textBlock1.Text = (string)e.Result));
}
}