从独立存储加载的图像根本没有约束力 [英] Image loaded from Isolated storage are not binding at all

查看:27
本文介绍了从独立存储加载的图像根本没有约束力的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从网络保存图像,将其加载到 BitmapImage 并尝试将图像控件与一些文本块一起绑定到 BitmapImage.问题是即使我调用 NotifyPropertyChanged 也不会显示图片.我可能会错过一些东西.

I save image from web, load it to BitmapImage and try to bind image control to BitmapImage along with some text chunks. Problem is pictures are not displayed even if I invoke NotifyPropertyChanged. I might miss something.

这是我的代码:

public class MovieData : INotifyPropertyChanged
{
    public int ID { get; set; }
    public bool Today { get; set; }
    public string DetailsUrl { get; set;  }
    public string Title { get; set;  }
    public string Country { get; set;  }
    public string Year { get; set; }
    public string Director { get; set;  }
    public string Genre { get; set; } 
    public string Duration { get; set; } 
    public string Restriction { get; set; } 
    public string Description { get; set; } 
    public string Poster { get; set; }
    public BitmapImage PosterLocal;
    public string LargePoster { get; set; }
    public BitmapImage LargePosterLocal { get; set; }
    public DateTime AirDate { get; set; }
    public DateTime LastDate { get; set; } 
    public string Cinema { get; set; } 
    public string IsDetailsLoaded { get; set; }
    public HttpResponseMessage HtmlRequest { get; set; }
    private static CancellationTokenSource _cts = new CancellationTokenSource();
    public bool IsTaskCanceled = false;

    public async Task<bool> GetDetailsAsync()
    {
        if (this.Year == null)
        {

            this.IsDetailsLoaded = "visible";
            NotifyPropertyChanged("IsDetailsLoaded");
            Uri uri = new Uri(this.DetailsUrl);
            HttpClient client = new HttpClient();
            HtmlDocument htmlDocument = new HtmlDocument();
            HtmlNode htmlNode = new HtmlNode(0, htmlDocument, 1);
            MovieData Item = new MovieData();
            string HtmlResult;

            try
            {
                HtmlRequest = await client.GetAsync(uri, _cts.Token);
                HtmlResult = await HtmlRequest.Content.ReadAsStringAsync();
            }
            catch (System.Net.Http.HttpRequestException e)
            {
                Console.Out.WriteLine(e.Message);
                HtmlResult = null;
                this.IsDetailsLoaded = "Collapsed";
                NotifyPropertyChanged("IsDetailsLoaded");
            }
            catch (System.Threading.Tasks.TaskCanceledException e)
            {
                Console.Out.WriteLine(e.Message);
                HtmlResult = null;
                this.IsDetailsLoaded = "Collapsed";
                NotifyPropertyChanged("IsDetailsLoaded");
            }

            if (!(HtmlResult == null) && HtmlRequest.IsSuccessStatusCode)
            {
                await this.DownloadPosterAsync();
                NotifyPropertyChanged("PosterLocal");
                htmlDocument.LoadHtml(HtmlResult);
                this.LargePoster = htmlDocument.DocumentNode.SelectSingleNode("//div[@class='cinema_img']/a").GetAttributeValue("href", "No poster image");
                NotifyPropertyChanged("LargePoster");
                await this.DownloadLargePosterAsync();
                NotifyPropertyChanged("LargePosterLocal");
                htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class='cinema_desc']");
                this.Title = GetStringFromNode(htmlNode.SelectSingleNode("h1"));
                NotifyPropertyChanged("Title");
                this.Country = GetStringFromNode(htmlNode.SelectSingleNode("p[2]"));
                NotifyPropertyChanged("Country");
                this.Year = GetStringFromNode(htmlNode.SelectSingleNode("p[3]"));
                NotifyPropertyChanged("Year");
                this.Director = GetStringFromNode(htmlNode.SelectSingleNode("p[4]"));
                NotifyPropertyChanged("Director");
                this.Genre = GetStringFromNode(htmlNode.SelectSingleNode("p[6]"));
                NotifyPropertyChanged("Genre");
                this.Duration = GetStringFromNode(htmlNode.SelectSingleNode("p[7]"));
                NotifyPropertyChanged("Duration");
                this.Restriction = GetStringFromNode(htmlNode.SelectSingleNode("p[8]"));
                NotifyPropertyChanged("Restriction");
                this.Description = GetStringFromNode(htmlNode.SelectSingleNode("p[9]/p"));
                NotifyPropertyChanged("Description");
                this.AirDate = GetAirDate(htmlNode.SelectSingleNode("p[1]"));
                NotifyPropertyChanged("AirDate");
                this.LastDate = GetLastDate(htmlNode.SelectSingleNode("p[1]"));
                NotifyPropertyChanged("LastDate");
                this.IsDetailsLoaded = "Collapsed";
                NotifyPropertyChanged("IsDetailsLoaded");

            }
        }
        return true;
    }

    #region public async Task<bool> DownloadPosterAsync() //Method for download images from web and save them to isolated storage with same name.
    public async Task<bool> DownloadPosterAsync()
    {
        WebClient client = new WebClient(); //Instantiate WebClient

        var isoStore = IsolatedStorageFile.GetUserStoreForApplication();
        string DestFileName = "small\\"+Path.GetFileName(this.Poster);
        if (!isoStore.FileExists(DestFileName))
        {
            client.OpenReadAsync(new Uri(this.Poster));

            client.OpenReadCompleted += (s, e) => //Wait for completion
            {


                if (!isoStore.DirectoryExists("small"))
                {
                    isoStore.CreateDirectory("small");
                }
                var tempBitmap = new BitmapImage(); //Create temp bitmap container
                tempBitmap.SetSource(e.Result); //Copy stream to bitmap container
                var writeableBitmap = new WriteableBitmap(tempBitmap); //Create WriteableBitmap out of temp bitmap
                using (var isoFileStream = isoStore.CreateFile(DestFileName)) //Create file in Isolated Storage
                {
                    var width = writeableBitmap.PixelWidth; //Set attributes
                    var height = writeableBitmap.PixelHeight; // Set some more
                    Extensions.SaveJpeg(writeableBitmap, isoFileStream, width, height, 0, 100); //Finally save .jpeg
                }

            };
        }
        BitmapImage image = null;
        using (var imageStream = await LoadImageAsync(DestFileName))
        {
            if (imageStream != null)
            {
                image = new BitmapImage();
                image.SetSource(imageStream);
            }
        }
        this.PosterLocal = image;
        return true;
    }
    #endregion

和 XAML 块:

<phone:PhoneApplicationPage.Resources>

    <DataTemplate x:Key="MoviesDataTemplate">
        <Grid Margin="12,7,0,5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Image Source="{Binding PosterLocal}" Width="99" Height="136" Grid.Column="0" Stretch="UniformToFill" CacheMode="BitmapCache"/>
            <StackPanel Margin="0,0,0,0" Grid.Column="1">
                <TextBlock Text="{Binding Title}" TextWrapping="NoWrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
                <TextBlock TextWrapping="Wrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextAccentStyle}">
                    <Run Text="{Binding AirDate, StringFormat=MMMM dd\, yyyy}" ></Run>
                </TextBlock> 
                <!--<TextBlock Text="{Binding AirTimes}" TextWrapping="Wrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>-->
                <ProgressBar IsIndeterminate="True" Visibility="{Binding IsDetailsLoaded}" Margin="0,12"></ProgressBar>
            </StackPanel>
        </Grid>
    </DataTemplate>

</phone:PhoneApplicationPage.Resources>

我搜索了 SO 并找到了很多主题,但没有找到解决方案.我想我的问题是在 Datacontext 分配后图像加载,并且 NotifyPropertyChanged 不适用于位图图像,因为每个 over 属性同时分配并在控制中显示.我还检查了图像是否实际下载、存储在独立存储中并已加载.(硬编码图像到属性并且它有效).任何关于如何使绑定工作的建议?

I search through SO and found lots of topics but didn't find resolution. I guess my problem is that image loading after Datacontext assigning, and NotifyPropertyChanged does not work for bitmap images because every over property assigns at the same time and shows in control. Also I checked that images actually downloaded, stored at Isolated Storage and was loaded . (Hard coded image to property and it worked). Any suggestions how to make binding work?

推荐答案

您应该绑定到属性,并且在您提供的代码中 - PosterLocal 不是属性.在这种情况下,您可以尝试使用 PosterLocal 这样的 getter:

You should Bind to properties, and in the code you provided - PosterLocal is not a property. In this case you can try to use such a getter of your PosterLocal:

public BitmapImage PosterLocal
{
   get
   {
       BitmapImage temp = new BitmapImage();

       using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
       using (IsolatedStorageFileStream file = ISF.OpenFile(posterLocal, FileMode.Open, FileAccess.Read))
            temp.SetSource(file);
       return temp;
    }
}

private string posterLocal; // this in case you probably will need to save somewhere the file name

如果您只需要 PosterLocal 用于绑定(单向),那么 getter 就足够了.以及您使用 string posterLocal 更改的文件名.

If you need your PosterLocal only for binding (one-way) then getter should be sufficient. And the filename you change with string posterLocal.

在这种情况下,您不再需要 DownloadPosterAsync 中的一部分代码 - 将使用 PropertyChanged 激活 getter.将文件保存到 IS 后立即执行:

In this case you no longer need a part of your code in DownloadPosterAsync - getter will be activated with PropertyChanged. Just after saving file to IS do:

posterLocal = DestFileName;

这篇关于从独立存储加载的图像根本没有约束力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆