异步加载图像

时间:2012-02-07 10:27:42

标签: image windows-phone-7 binding asynchronous windows-phone

我想用最好的方式在我的PanoramaPage中显示图像。我下载了一个页面并显示了它的信息然后我想异步加载带有图像的另一个页面。所以我使用的是HttpWebRequest,我得到了回复。一切都很好,希望这是最好的方式。所以我创建了我的GaleryViewModel,对于页面上的所有图像,我将url添加到我的班级。 而且有一个问题。我看不到图像。这是我的观点:

<ListBox ItemsSource="{Binding Images}" x:Name="listImages" Height="652" Canvas.Top="80">
    <ListBox.ItemTemplate>
        <DataTemplate>
           <StackPanel Orientation="Horizontal" Margin="0,0,0,17">
               <Image Height="100" Width="100" Margin="12,0,9,0" >
                   <Image.Source>
                       <BitmapImage UriSource="{Binding ImgURL}" CreateOptions="BackgroundCreation"/>
                   </Image.Source>
               </Image>
               <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
           </StackPanel>
       </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

这是我的WebResponse事件处理程序的内容:

MovieExt movie = this.DataContext as MovieExt;

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(response);

var photos = from ti in doc.DocumentNode.Descendants("div")
             where ti.Attributes["class"] != null && ti.Attributes["class"].Value == "photo"
             select ti;
Regex rgx = new Regex("http://[0-9a-zA-Z_./]+");

foreach (var photo in photos)
{
    GaleryViewModel fotka = new GaleryViewModel();
    string style = photo.Attributes["style"].Value;

    MatchCollection matches = rgx.Matches(style);
    if (matches.Count > 0)
    {
        foreach (Match match in matches)
            fotka.ImgURL = match.Value;
    }
    fotka.LineOne = "Test";
    movie.Images.Add(fotka);
}
this.DataContext = movie;
this.listImages.ItemsSource = movie.Images;

以及所有GaleryViewModel和MovieExt:

    public class GaleryViewModel : INotifyPropertyChanged
    {
      private string _imgUrl;
      public string ImgURL
      {
        get
        {
            return _imgUrl;
        }
        set
        {
            if (value != _imgUrl)
            {
                _imgUrl = value;
                NotifyPropertyChanged("ImgURL");
            }
        }
    }

    private string _lineOne;
    public string LineOne
    {
        get
        {
            return _lineOne;
        }
        set
        {
            if (value != _lineOne)
            {
                _lineOne = value;
                NotifyPropertyChanged("LineOne");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public class MovieExt
{
    public string Title { get; set; }
    public string Year { get; set; }
    public string Url { get; set; }
 ...
    public List<GaleryViewModel> Images { get; set; }
 ...
 }

我不确定我做错了什么,但我认为这是有约束力的。谢谢你的帮助

3 个答案:

答案 0 :(得分:0)

看着这看起来你没有通知MovieExt.Images属性已经改变。如果不这样做,ListBox将不会更新其Items。为此,MovieExt还需要支持INotifyPropertyChanged

答案 1 :(得分:0)

您必须将Uri转换为BitmapImage,因为BitmapImage UriSource是一个流。请看一下:Image UriSource and Data Binding

答案 2 :(得分:0)

将加载方法(仅用于测试)替换为:

MovieExt movie = new MovieExt();
movie.Images = new List<GaleryViewModel>();
GaleryViewModel fotka1 = new GaleryViewModel();
fotka1.LineOne = "line1";
fotka1.ImgURL = "http://proservice.kiev.ua/wp-content/uploads/2011/10/apple-logo.jpg";
GaleryViewModel fotka2 = new GaleryViewModel();
fotka2.LineOne = "line2";
fotka2.ImgURL = "http://www.mykhailenko.com/blog/wp-content/uploads/2010/12/apple-logo-history-2.png";
movie.Images.Add(fotka1);
movie.Images.Add(fotka2);
listImages.ItemsSource = movie.Images;

并且有效

我猜问题就在这一行:

if (matches.Count > 0)

您没有匹配项,因此Url为空

您能否在上下文中向我们提供服务返回调试代码的数据?

另外,为什么你需要循环来进行这项任务呢?

foreach (Match match in matches)
    fotka.ImgURL = match.Value;