如何使用WP Team的MediaViewer类来显示150多张图像?

时间:2014-08-23 18:32:11

标签: c# xaml windows-phone-8 windows-phone media

我正在开发一个Windows Phone 8应用程序。它基本上是支持缩放的图像查看器。用户可以向左滑动&正确切换图像。我还想添加索引输入,以便用户可以跳转到该特定图像。我正在寻找和遇到了名为PhoneMediaViewer的NuGet包。还有名为Basic Lens sample的MSDN示例使用该媒体查看器。我检查了代码&我没有得到代码。请帮助我解决如何在媒体查看器控制的情况下显示支持缩放的本地150多张图像。

1 个答案:

答案 0 :(得分:4)

Windows Phone编程本身可能很难,对新的异步有深刻的理解,等待关键字成为甚至noob教程的必需品。然后,再次使用Phones本地文件系统,即。 IsolatedStorage将对Streams有一个很好的理解,让你起步和前进。 .Net通常做了很好的工作,为您完成大部分工作,但在Windows Phone中,您绝对可以自己处理这些任务。

要使用MediaViewer控件,您只需将Nuget包安装到您正在使用的项目中即可。然后,您将需要向MediaViewer控件Items属性提供IThumbnailedImage列表。 nuget附带两个实现此接口的类,LocalFolderThumbnailedImage和MediaLibraryThumbnailedImage,其中第一个用于存储在电话上的本地图像,即。 IsolatedStorage,后者适用于媒体库中的图像项目。要使用MediaLibraryThumbnailedImage类,请确保已在WMAppManifest.xml文件中允许ID_CAP_MEDIALIB_PHOTO功能,否则将不会在您的调用中返回相册。

但是,如果您想使用在线可用的图像,则必须实现另一个类。我打电话给我的OnlineMediaThumbnailedImage。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Phone.Controls;

namespace MobileWin8Phone.ImageItem
{
    class OnlineMediaThumbnailedImage : IThumbnailedImage
    {
        private Stream _stream;
        private string _imageUrl;

        /// <summary>
        /// This class implements the IThumbnailedImage interface so that it can be
        /// consumed by the MediaViewer control.  Obtain the Stream of an image and
        /// pass it in so that the MediaViewer control can call GetImage() when needed.
        /// </summary>
        /// <param name="theImageStream"></param>
        /// <param name="imageUrl"></param>
        public OnlineMediaThumbnailedImage(Stream theImageStream, string imageUrl = "")
        {
            _stream = theImageStream;
            _imageUrl = imageUrl;
        }

        /// <summary>
        /// Returns a Stream representing the thumbnail image.
        /// </summary>
        /// <returns>Stream of the thumbnail image.</returns>
        public Stream GetThumbnailImage()
        {
            return this._stream;
        }

        /// <summary>
        /// Returns a Stream representing the full resolution image.
        /// </summary>
        /// <returns>Stream of the full resolution image.</returns>
        public Stream GetImage()
        {
            return this._stream;
        }

        /// <summary>
        /// Represents the time the photo was taken, useful for sorting photos.
        /// </summary>
        public System.DateTime DateTaken
        {
            get
            {
                return System.DateTime.Today;
            }
        }
    }
}

此类的调用者负责获取他们想要显示的图像流。由于我们正在使用Windows Phone,所有调用都应标记为Async,以便它们可以运行完成并允许UI线程尽快返回处理。以下是我用来存放MediaViewer控件的页面的示例代码。

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    //Initialize Items
    List<IThumbnailedImage> theImages = new List<IThumbnailedImage>();
    mvControl.Items = new ObservableCollection<object>(theImages);

    //Begin downloading images.
    await LoadImages();
}

private async Task LoadImages()
{
    try
    {
        await LoadFromOnlineMedia();
    }
    catch (Exception ex)
    {
        string pauseHere = "";
    }
}

private async Task LoadFromOnlineMedia()
{
    await DownloadImageFile("http://www.fnordware.com/superpng/pnggrad16rgb.png");
    await DownloadImageFile("http://www.fnordware.com/superpng/pnggrad16rgba.png");
    await DownloadImageFile("http://www.fnordware.com/superpng/pngtest16rgba.png");
}

private async Task DownloadImageFile(string imageUrl)
{
    WebClient theClient = new WebClient();
    theClient.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
    theClient.OpenReadAsync(new System.Uri(imageUrl));
}

void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    //Add Image to the Items collection via the UI Thread.
    Dispatcher.BeginInvoke(() => { mvControl.Items.Add(new OnlineMediaThumbnailedImage(e.Result)); });
}

当页面导航到我们时,我们输入OnNavigatedTo方法。此方法标记为异步,以便我们可以调用并等待其中的其他异步方法。我们首先创建一个空List并初始化mvController.Items集合。这可以在这里做,因为我们仍然在主UI线程上。

接下来,我们等待我们调用加载图像,以便它可以关闭并执行其操作,UI线程可以返回捕获用户交互。 LoadOnlineMedia方法使用WebClients从给定的URL读取图像流。回调用于此功能,因为这是Windows Phone编程,所有网络调用必须是异步的。如果我们省略await关键字,则异步方法将同步运行,并且不会处理任何网络调用。

如果您从UI线程调用,基本上您的Callback方法将永远不会被任何WebClient调用命中。

一旦回调被击中,我们就会使用返回的Stream来构建一个OnlineMediaThumbnailedImage。我们使用Dispatcher调用BeginInvoke将此项添加到Items集合,因为必须在UI线程上完成对UI或UI集合所做的任何操作。

Dispatcher自动返回UI线程以完成其工作,无论从哪个线程调用它。一旦我们将项目添加到集合中,MediaViewer控件将使用Virtulization来决定何时加载图像。基本上它加载了前5个图像,并且当它们进入范围时继续加载更多图像。当MediaViewer准备好加载Image时,它会调用GetImage或GetThumbnailImage来返回要查看的Image的Stream。如果您希望用自己的类覆盖IThumbnailImage,请记住覆盖这些方法并以您认为合适的任何方式提供Image流。