OnRender ( DrawingContext oDrawingContext, Double dAdjustedNearValue, Double dAdjustedNearOffset, Double dAdjustedFarValue, Double dAdjustedFarOffset ) { Debug.Assert(oDrawingContext != null); Debug.Assert(dAdjustedNearOffset >= 0); Debug.Assert(dAdjustedFarOffset >= 0); AssertValid(); Rect oClientRectangle = new Rect(0, 0, this.ActualWidth, this.ActualHeight); Double dAxisLength = m_bIsXAxis ? this.ActualWidth : this.ActualHeight; if (dAxisLength == 0) { return; } // If the pen is not one pixel wide, gridlines drawn on a large-font // machine vary in width, depending on their position. Pen oPen = WpfGraphicsUtil.CreateOnePixelPen(this, SystemColors.WindowTextBrush); WpfGraphicsUtil.FreezeIfFreezable(oPen); DrawBackground(oDrawingContext, oClientRectangle, dAdjustedNearOffset, dAdjustedFarOffset); DrawAxisLine(oDrawingContext, oClientRectangle, oPen); if (dAdjustedFarValue == dAdjustedNearValue) { // This is a degenerate case. Draw just one gridline. DrawMajorGridlineAndValue(oDrawingContext, oClientRectangle, oPen, dAdjustedNearValue, dAdjustedNearOffset, "N"); return; } if (dAdjustedNearOffset + dAdjustedFarOffset > dAxisLength) { return; } DrawLabel(oDrawingContext, oClientRectangle); Double [] adMajorGridlineValues; Int32 iDecimalPlacesToShow; ChartUtil.GetAxisGridlineValues(dAdjustedNearValue, dAdjustedFarValue, out adMajorGridlineValues, out iDecimalPlacesToShow); String sFormatSpecifier = GetFormatSpecifier(adMajorGridlineValues, iDecimalPlacesToShow); // Use the point-slope equation of a line to get the major gridline // coordinates. Double dX1 = dAdjustedNearValue; Double dY1 = dAdjustedNearOffset; Double dX2 = dAdjustedFarValue; Double dY2 = dAxisLength - dAdjustedFarOffset; Debug.Assert(dX1 != dX2); Double dM = (dY1 - dY2) / (dX1 - dX2); Double dPreviousMajorGridlineOffset = Double.NaN; foreach (Double dMajorGridlineValue in adMajorGridlineValues) { // Compute the major gridline's offset, then draw it. Double dMajorGridlineOffset = dY1 + dM * (dMajorGridlineValue - dX1); DrawMajorGridlineAndValue(oDrawingContext, oClientRectangle, oPen, dMajorGridlineValue, dMajorGridlineOffset, sFormatSpecifier); if (!Double.IsNaN(dPreviousMajorGridlineOffset)) { // Draw minor gridlines between the major gridlines. DrawMinorGridlines(oDrawingContext, oClientRectangle, oPen, dMajorGridlineOffset, dPreviousMajorGridlineOffset); } dPreviousMajorGridlineOffset = dMajorGridlineOffset; } }
GetImageSynchronousHttp ( Uri uri ) { Debug.Assert(uri != null); Debug.Assert(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps); AssertValid(); // Talk about inefficient... // // The following code uses HttpWebRequest to synchronously download the // image into a List<Byte>, then passes that List as a MemoryStream to // BitmapImage.StreamSource. It works, but it involves way too much // Byte copying. There has to be a better way to do this, but so far I // haven't found one. // // In the following post... // // http://stackoverflow.com/questions/426645/ // how-to-render-an-image-in-a-background-wpf-process // // ...the poster suggests feeding the WebResponse.GetResponseStream() // indirectly to BitmapImage.StreamSource. This sometimes works but // sometimes doesn't, which you can tell by checking // BitmapImage.IsDownloading at the end of his code. It is true // sometimes, indicating that the Bitmap is still downloading. HttpWebRequest oHttpWebRequest = (HttpWebRequest)WebRequest.Create(uri); oHttpWebRequest.Timeout = HttpWebRequestTimeoutMs; oHttpWebRequest.CachePolicy = new RequestCachePolicy( RequestCacheLevel.CacheIfAvailable); WebResponse oWebResponse = oHttpWebRequest.GetResponse(); BinaryReader oBinaryReader = new BinaryReader( oWebResponse.GetResponseStream()); List <Byte> oResponseBytes = new List <Byte>(); while (true) { Byte [] abtSomeResponseBytes = oBinaryReader.ReadBytes(8192); if (abtSomeResponseBytes.Length == 0) { break; } oResponseBytes.AddRange(abtSomeResponseBytes); } Byte [] abtAllResponseBytes = oResponseBytes.ToArray(); oResponseBytes = null; MemoryStream oMemoryStream = new MemoryStream(abtAllResponseBytes, false); BitmapImage oBitmapImage = new BitmapImage(); oBitmapImage.BeginInit(); oBitmapImage.StreamSource = oMemoryStream; oBitmapImage.EndInit(); WpfGraphicsUtil.FreezeIfFreezable(oBitmapImage); return(oBitmapImage); }
OnRender ( DrawingContext drawingContext ) { AssertValid(); Double dAxisLength = m_bIsXAxis ? this.ActualWidth : this.ActualHeight; if (dAxisLength == 0) { return; } Double dNearValue, dNearOffset, dFarValue, dFarOffset; if (m_bIsXAxis) { dNearValue = m_dNearValue; dNearOffset = m_dNearOffset; dFarValue = m_dFarValue; dFarOffset = m_dFarOffset; } else { // The y-axis has to be flipped, so that increasing values run // from bottom to top. dNearValue = m_dFarValue; dNearOffset = m_dFarOffset; dFarValue = m_dNearValue; dFarOffset = m_dNearOffset; } // Figure out where the offsets fall after being transformed. Double dAdjustedNearOffset = WpfGraphicsUtil.TransformLength( dNearOffset, m_oDockedControlRenderTransform, m_bIsXAxis); Double dFarX = dAxisLength - dFarOffset; Double dAdjustedFarX = WpfGraphicsUtil.TransformLength( dFarX, m_oDockedControlRenderTransform, m_bIsXAxis); if (dAdjustedFarX == dAdjustedNearOffset) { DrawOffsetBackground(drawingContext, new Rect(0, 0, this.ActualWidth, this.ActualHeight)); return; } Double dAdjustedNearValue = dNearValue; Double dAdjustedFarValue = dFarValue; // Use the point-slope equation of a line to map adjusted offsets to // values, if necessary. Double dX1 = dAdjustedNearOffset; Double dY1 = dNearValue; Double dX2 = dAdjustedFarX; Double dY2 = dFarValue; Debug.Assert(dX1 != dX2); Double dM = (dY1 - dY2) / (dX1 - dX2); if (dAdjustedNearOffset < 0) { // Find the value at the near end of the axis. dAdjustedNearValue = dY1 + dM * (0 - dX1); dAdjustedNearOffset = 0; } Double dAdjustedFarOffset; if (dAdjustedFarX <= dAxisLength) { dAdjustedFarOffset = dAxisLength - dAdjustedFarX; } else { // Find the value at the far end of the axis. dAdjustedFarValue = dY1 + dM * (dAxisLength - dX1); dAdjustedFarOffset = 0; } if (m_bIsXAxis) { OnRender(drawingContext, dAdjustedNearValue, dAdjustedNearOffset, dAdjustedFarValue, dAdjustedFarOffset); } else { // The y-axis is flipped. OnRender(drawingContext, dAdjustedFarValue, dAdjustedFarOffset, dAdjustedNearValue, dAdjustedNearOffset); } }
GetImageSynchronous ( String uriString ) { Debug.Assert(!String.IsNullOrEmpty(uriString)); AssertValid(); const Int32 ErrorImageWidthAndHeight = 52; Uri oUri; if (Uri.TryCreate(uriString, UriKind.Absolute, out oUri)) { if (oUri.Scheme == Uri.UriSchemeHttp || oUri.Scheme == Uri.UriSchemeHttps) { try { return(GetImageSynchronousHttp(oUri)); } catch (WebException) { // (These empty catch blocks cause an error image to be // returned.) } catch (ArgumentException) { /* * Attempting to download a possibly corrupt image from this * Twitter URL: * * http://a1.twimg.com/profile_images/1112245377/ * Photo_on_2010-08-27_at_18.51_normal.jpg * * raised the following exception: * * [ArgumentException]: An invalid character was found in text * content. * at System.Windows.Media.Imaging.BitmapFrameDecode. * get_ColorContexts() * at System.Windows.Media.Imaging.BitmapImage. * FinalizeCreation() * at System.Windows.Media.Imaging.BitmapImage.EndInit() */ } catch (IOException) { /* * Attempting to download a possibly corrupt image from this * Twitter URL: * * http://a2.twimg.com/profile_images/1126755034/ * 8FjbVD_normal.gif * * raised the following exception: * * [IOException]: Cannot read from the stream. * [COMException]: Exception from HRESULT: 0x88982F72 * at System.Windows.Media.Imaging.BitmapDecoder. * SetupDecoderFromUriOrStream(Uri uri, Stream stream, * BitmapCacheOption cacheOption, Guid& clsId, Boolean& * isOriginalWritable, Stream& uriStream, * UnmanagedMemoryStream& unmanagedMemoryStream, * SafeFileHandle& safeFilehandle) * ... */ } catch (NotSupportedException) { /* * Attempting to download a possibly corrupt image from a * Twitter URL (didn't record the URL) raised the following * exception: * * [NotSupportedException]: No imaging component suitable * to complete this operation was found. */ } } else if (oUri.Scheme == Uri.UriSchemeFile) { try { BitmapImage oBitmapImage = new BitmapImage(oUri); WpfGraphicsUtil.FreezeIfFreezable(oBitmapImage); return(oBitmapImage); } catch (IOException) { } catch (NotSupportedException) { // Invalid image file. } catch (UnauthorizedAccessException) { // The URI is actually a folder, for example. } } } if (m_oCachedErrorImage == null) { m_oCachedErrorImage = CreateErrorImage(ErrorImageWidthAndHeight); } return(m_oCachedErrorImage); }