using System; using System.Collections.Generic; using System.Linq; 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 System.IO; using System.Net; using System.Windows.Resources; using System.Windows.Media.Imaging; using System.Xml; using SL.XAML.SilverlightControls; namespace SL.XAML.MediaViewer { public partial class Page : UserControl { private PictureControl currentPicture; private WebClient webClient; private string siteUrl; private string mediaType; private string pictureLibName; private Stream body; private bool canClippingRegionScroll = false; private double heightPictureItem = 80.0; private double heightTotalClippingCanvas = 0.0; private double visibleClippingRegion = 500.0; private double maxContentTopPosition = 1.0; private System.Threading.SynchronizationContext syncContext; public Page(string siteUrl, string mediaType, string picLibName, double actualHeight) { InitializeComponent(); // resize the Canvas if the height of the web part is different from that of the silverlight canvas if (actualHeight > 0.0) ResizeCanvas(actualHeight); visibleClippingRegion = ClippingCanvas.Height; // web client is used to download images and movies. For this type of files an eventhandler for OpenReadCompleted should be added. webClient = new WebClient(); webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted); if (!string.IsNullOrEmpty(siteUrl) && !string.IsNullOrEmpty(picLibName)) { this.siteUrl = siteUrl; this.pictureLibName = picLibName; this.mediaType = mediaType; BuildPreviewBar(); } else { NoCdTextBlock.Visibility = Visibility.Visible; } } // Resize the canvas by using the ScaleTransform private void ResizeCanvas(double newHeight) { if (newHeight != MasterCanvas.Height) { ScaleTransform rootScale = (ScaleTransform)this.FindName("RootScale"); double newScale = newHeight / this.Height; rootScale.ScaleX = rootScale.ScaleY = newScale; } } // If the download completed successfully show the image or movie. void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) { if (e.Error == null & !e.Cancelled) { Stream stream = e.Result; switch (mediaType) { case "Movie": LargeMovie.Visibility = Visibility.Visible; LargePicture.Visibility = Visibility.Collapsed; LargeMovie.SetSource(stream); break; case "Picture": LargeMovie.Visibility = Visibility.Collapsed; LargePicture.Visibility = Visibility.Visible; StreamResourceInfo sri = new StreamResourceInfo(e.Result as Stream, null); BitmapImage imgsrc = new BitmapImage(); imgsrc.SetSource(sri.Stream); LargePicture.Source = imgsrc; break; } } } // Information of the images or movies that should be downloaded is obtained by calling the SharePoint Lists.asmx web service // using HttpWebRequest. The call to the Request as to the Response are asynchronous. private void BuildPreviewBar() { syncContext = System.Threading.SynchronizationContext.Current; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(siteUrl + "/_vti_bin/Lists.asmx", UriKind.Absolute)); request.Method = "POST"; request.ContentType = "application/soap+xml; charset=utf-8"; request.BeginGetRequestStream(new AsyncCallback(RequestCallback), request); } // in the request a soap envelop is build based on the schema needed by the Lists.asmx. The GetListItems method is called on // the picture library selected by the user (in the web part). private void RequestCallback(IAsyncResult asyncResult) { string envelope = @" {0} False "; envelope = string.Format(envelope, pictureLibName); HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState; body = request.EndGetRequestStream(asyncResult); System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); byte[] formBytes = encoding.GetBytes(envelope); body.Write(formBytes, 0, formBytes.Length); request.BeginGetResponse(new AsyncCallback(ResponseCallback), request); } // In the response callback the resulting list items are used to create small picture controls that will // appear at the right of the root canvas. They will be positioned vertically within a clipping region. If // more items are returned than can be displayed on the canvas, scroll buttons are made visible. // The first picture is displayed in a larger format. private void ResponseCallback(IAsyncResult asyncResult) { HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState; HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult); syncContext.Post(ExtractResponse, response); } private void ExtractResponse(object state) { HttpWebResponse response = (HttpWebResponse)state; Stream content = response.GetResponseStream(); if (response.StatusCode == HttpStatusCode.OK) { using (XmlReader reader = XmlReader.Create(new StreamReader(content))) { int previewcounter = 0; double toppos = 0.0; double leftpos = 2; while (reader.Read()) { if (reader.IsStartElement("row", "#RowsetSchema")) { previewcounter++; reader.MoveToAttribute("ows_Title"); string title = reader.Value; reader.MoveToAttribute("ows_Description"); string description = reader.Value; reader.MoveToAttribute("ows_EncodedAbsUrl"); string mediaurl = reader.Value; string[] urlvalues = mediaurl.Split(','); if (urlvalues.Length == 2) mediaurl = urlvalues[0]; // Create a preview picture PictureControl picture = CreateNewPictureControl(title, description, mediaurl); // Add the picture to the left side of the canvas picture.SetValue(Canvas.TopProperty, toppos); picture.SetValue(Canvas.LeftProperty, leftpos); picture.Visibility = Visibility.Visible; picture.MouseLeftButtonDown += new MouseButtonEventHandler(picture_MouseLeftButtonDown); ClippingCanvas.Children.Add(picture); if (previewcounter == 1) { picture.SetBorder(true); currentPicture = picture; LoadLargePicture(mediaurl, title, description); } toppos += 82; heightTotalClippingCanvas += heightPictureItem; reader.MoveToElement(); //Moves the reader back to the element node. } } } } body.Close(); LoadingCanvas.Visibility = Visibility.Collapsed; // if the total height is lower than the height of the scrolling region, we don't need to be able to scroll if (heightTotalClippingCanvas > ClippingCanvas.Height) { canClippingRegionScroll = true; ScrollUpButton.Visibility = Visibility.Visible; ScrollDownButton.Visibility = Visibility.Visible; } else { canClippingRegionScroll = false; ScrollUpButton.Visibility = Visibility.Collapsed; ScrollDownButton.Visibility = Visibility.Collapsed; } } private void picture_MouseLeftButtonDown(object sender, MouseEventArgs e) { // set the border of the preview picture currentPicture.SetBorder(false); currentPicture = (PictureControl)sender; // reset the main picture and fields currentPicture.SetBorder(true); // fill the controls LoadLargePicture(currentPicture.MediaUrl, currentPicture.Title, currentPicture.Description); // set the opacity of the image Storyboard fadeIn = (Storyboard)this.FindName("FadeInImageStoryBoard"); if (fadeIn != null) fadeIn.Begin(); } // Creates the picture control and set its properties private PictureControl CreateNewPictureControl(string title, string description, string url) { PictureControl picture = new PictureControl(mediaType); picture.Title = title; picture.Description = description; picture.MediaUrl = url; return picture; } // Loads the selected picture on the large canvas. If title and/or description are filled out, // they will be desplayed in a canvas at the bottom of the picture. private void LoadLargePicture(string mediaUrl, string title, string description) { LargePicture.Visibility = Visibility.Collapsed; LargeMovie.Visibility = Visibility.Collapsed; Uri openUri = new Uri(mediaUrl, UriKind.Absolute); webClient.OpenReadAsync(openUri); if (string.IsNullOrEmpty(title) && string.IsNullOrEmpty(description)) { TitleCanvas.Visibility = Visibility.Collapsed; } else { TitleCanvas.Visibility = Visibility.Visible; if (!string.IsNullOrEmpty(title)) TitleTextBlock.Text = title; else TitleTextBlock.Text = string.Empty; if (!string.IsNullOrEmpty(description)) DescriptionTextBlock.Text = description; else DescriptionTextBlock.Text = string.Empty; } } private void ScrollUp_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (!canClippingRegionScroll) return; double top = (double)ClippingCanvas.GetValue(Canvas.TopProperty); if ((top + heightPictureItem + 2) <= maxContentTopPosition) { Storyboard sbScrollUp = (Storyboard)this.FindName("scrollUp"); if (sbScrollUp != null) { sbScrollUp.Begin(); visibleClippingRegion -= heightPictureItem; } } } private void ScrollDown_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (!canClippingRegionScroll) return; if (visibleClippingRegion < heightTotalClippingCanvas) { Storyboard sbScrollDown = (Storyboard)this.FindName("scrollDown"); if (sbScrollDown != null) { sbScrollDown.Begin(); visibleClippingRegion += heightPictureItem; } } } } }