Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / WinForms / Managed / System / WinForms / PictureBox.cs / 2 / PictureBox.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System.Runtime.Serialization.Formatters; using System.Runtime.InteropServices; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System; using System.IO; using System.Security.Permissions; using System.Drawing; using System.Net; using System.ComponentModel; using System.ComponentModel.Design; using System.Threading; using System.Windows.Forms.Layout; using Microsoft.Win32; ////// /// [ ComVisible(true), ClassInterface(ClassInterfaceType.AutoDispatch), DefaultProperty("Image"), DefaultBindingProperty("Image"), Docking(DockingBehavior.Ask), Designer("System.Windows.Forms.Design.PictureBoxDesigner, " + AssemblyRef.SystemDesign), SRDescription(SR.DescriptionPictureBox) ] public class PictureBox : Control, ISupportInitialize { ///Displays an image that can be a graphic from a bitmap, /// icon, or metafile, as well as from /// an enhanced metafile, JPEG, or GIF files. ////// /// The type of border this control will have. /// private BorderStyle borderStyle = System.Windows.Forms.BorderStyle.None; ////// /// The image being displayed. /// private Image image; ////// /// Controls how the image is placed within our bounds, or how we are /// sized to fit said image. /// private PictureBoxSizeMode sizeMode = PictureBoxSizeMode.Normal; private Size savedSize; bool currentlyAnimating; // Instance members for asynchronous behavior private AsyncOperation currentAsyncLoadOperation = null; private string imageLocation; private Image initialImage; private Image errorImage; private int contentLength; private int totalBytesRead; private MemoryStream tempDownloadStream; private const int readBlockSize = 4096; private byte[] readBuffer = null; private ImageInstallationType imageInstallationType; private SendOrPostCallback loadCompletedDelegate = null; private SendOrPostCallback loadProgressDelegate = null; private bool handleValid = false; private object internalSyncObject = new object(); // These default images will be demand loaded. private Image defaultInitialImage = null; private Image defaultErrorImage = null; [ ThreadStatic ] private static Image defaultInitialImageForThread = null; [ ThreadStatic ] private static Image defaultErrorImageForThread = null; private static readonly object defaultInitialImageKey = new object(); private static readonly object defaultErrorImageKey = new object(); private static readonly object loadCompletedKey = new object(); private static readonly object loadProgressChangedKey = new object(); private const int PICTUREBOXSTATE_asyncOperationInProgress = 0x00000001; private const int PICTUREBOXSTATE_cancellationPending = 0x00000002; private const int PICTUREBOXSTATE_useDefaultInitialImage = 0x00000004; private const int PICTUREBOXSTATE_useDefaultErrorImage = 0x00000008; private const int PICTUREBOXSTATE_waitOnLoad = 0x00000010; private const int PICTUREBOXSTATE_needToLoadImageLocation = 0x00000020; private const int PICTUREBOXSTATE_inInitialization = 0x00000040; // PERF: take all the bools and put them into a state variable private System.Collections.Specialized.BitVector32 pictureBoxState; // see PICTUREBOXSTATE_ consts above ////// /// public PictureBox() { // this class overrides GetPreferredSizeCore, let Control automatically cache the result SetState2(STATE2_USEPREFERREDSIZECACHE, true); pictureBoxState = new System.Collections.Specialized.BitVector32(PICTUREBOXSTATE_useDefaultErrorImage | PICTUREBOXSTATE_useDefaultInitialImage); SetStyle(ControlStyles.Opaque |ControlStyles.Selectable , false); SetStyle(ControlStyles.OptimizedDoubleBuffer|ControlStyles.SupportsTransparentBackColor, true); TabStop = false; savedSize = Size; } ///Creates a new picture with all default properties and no /// Image. The default PictureBox.SizeMode will be PictureBoxSizeMode.NORMAL. /// ////// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override bool AllowDrop { get { return base.AllowDrop; } set { base.AllowDrop = value; } } ////// /// [ DefaultValue(BorderStyle.None), SRCategory(SR.CatAppearance), DispId(NativeMethods.ActiveX.DISPID_BORDERSTYLE), SRDescription(SR.PictureBoxBorderStyleDescr) ] public BorderStyle BorderStyle { get { return borderStyle; } set { //valid values are 0x0 to 0x2 if (!ClientUtils.IsEnumValid(value, (int)value, (int)BorderStyle.None, (int)BorderStyle.Fixed3D)){ throw new InvalidEnumArgumentException("value", (int)value, typeof(BorderStyle)); } if (borderStyle != value) { borderStyle = value; RecreateHandle(); AdjustSize(); } } } // Try to build a URI, but if that fails, that means it's a relative // path, and we treat it as relative to the working directory (which is // what GetFullPath uses). private Uri CalculateUri(string path) { Uri uri; try { uri = new Uri(path); } catch (UriFormatException) { // It's a relative pathname, get its full path as a file. path = Path.GetFullPath(path); uri = new Uri(path); } return uri; } ///Indicates the /// border style for the control. ///[ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxCancelAsyncDescr) ] public void CancelAsync() { pictureBoxState[PICTUREBOXSTATE_cancellationPending] = true; } /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new bool CausesValidation { get { return base.CausesValidation; } set { base.CausesValidation = value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler CausesValidationChanged { add { base.CausesValidationChanged += value; } remove { base.CausesValidationChanged -= value; } } /// /// /// /// protected override CreateParams CreateParams { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] get { CreateParams cp = base.CreateParams; switch (borderStyle) { case BorderStyle.Fixed3D: cp.ExStyle |= NativeMethods.WS_EX_CLIENTEDGE; break; case BorderStyle.FixedSingle: cp.Style |= NativeMethods.WS_BORDER; break; } return cp; } } ///Returns the parameters needed to create the handle. Inheriting classes /// can override this to provide extra functionality. They should not, /// however, forget to call base.getCreateParams() first to get the struct /// filled up with the basic info. ///protected override ImeMode DefaultImeMode { get { return ImeMode.Disable; } } /// /// /// Deriving classes can override this to configure a default size for their control. /// This is more efficient than setting the size in the control's constructor. /// protected override Size DefaultSize { get { return new Size(100, 50); } } ///[ SRCategory(SR.CatAsynchronous), Localizable(true), RefreshProperties(RefreshProperties.All), SRDescription(SR.PictureBoxErrorImageDescr) ] public Image ErrorImage { get { // Strange pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage] approach used // here to avoid statically loading the default bitmaps from resources at // runtime when they're never used. if (errorImage == null && pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage]) { if (defaultErrorImage == null) { // Can't share images across threads. if (defaultErrorImageForThread == null) { defaultErrorImageForThread = new Bitmap(typeof(PictureBox), "ImageInError.bmp"); } defaultErrorImage = defaultErrorImageForThread; } errorImage = defaultErrorImage; } return errorImage; } set { if (ErrorImage != value) { pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage] = false; } errorImage = value; } } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override Color ForeColor { get { return base.ForeColor; } set { base.ForeColor = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler ForeColorChanged { add { base.ForeColorChanged += value; } remove { base.ForeColorChanged -= value; } } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override Font Font { get { return base.Font; } set { base.Font = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler FontChanged { add { base.FontChanged += value; } remove { base.FontChanged -= value; } } /// /// /// [ SRCategory(SR.CatAppearance), Localizable(true), Bindable(true), SRDescription(SR.PictureBoxImageDescr) ] public Image Image { get { return image; } set { InstallNewImage(value, ImageInstallationType.DirectlySpecified); } } // The area occupied by the image ///Retrieves the Image that the ///is currently displaying. [ SRCategory(SR.CatAsynchronous), Localizable(true), DefaultValue(null), RefreshProperties(RefreshProperties.All), SRDescription(SR.PictureBoxImageLocationDescr) ] public string ImageLocation { get { return imageLocation; } set { // Reload even if value hasn't changed, since Image itself may // have changed. imageLocation = value; pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation] = !string.IsNullOrEmpty(imageLocation); // Reset main image if it hasn't been directly specified. if (string.IsNullOrEmpty(imageLocation) && imageInstallationType != ImageInstallationType.DirectlySpecified) { InstallNewImage(null, ImageInstallationType.DirectlySpecified); } if (WaitOnLoad && !pictureBoxState[PICTUREBOXSTATE_inInitialization] && !string.IsNullOrEmpty(imageLocation)) { // Load immediately, so any error will occur synchronously Load(); } Invalidate(); } } private Rectangle ImageRectangle { get { return ImageRectangleFromSizeMode(sizeMode); } } private Rectangle ImageRectangleFromSizeMode(PictureBoxSizeMode mode) { Rectangle result = LayoutUtils.DeflateRect(ClientRectangle, Padding); if (image != null) { switch (mode) { case PictureBoxSizeMode.Normal: case PictureBoxSizeMode.AutoSize: // Use image's size rather than client size. result.Size = image.Size; break; case PictureBoxSizeMode.StretchImage: // Do nothing, was initialized to the available dimensions. break; case PictureBoxSizeMode.CenterImage: // Center within the available space. result.X += (result.Width - image.Width) / 2; result.Y += (result.Height - image.Height) / 2; result.Size = image.Size; break; case PictureBoxSizeMode.Zoom: Size imageSize = image.Size; float ratio = Math.Min((float)ClientRectangle.Width / (float)imageSize.Width, (float)ClientRectangle.Height / (float)imageSize.Height); result.Width = (int)(imageSize.Width * ratio); result.Height = (int) (imageSize.Height * ratio); result.X = (ClientRectangle.Width - result.Width) /2; result.Y = (ClientRectangle.Height - result.Height) /2; break; default: Debug.Fail("Unsupported PictureBoxSizeMode value: " + mode); break; } } return result; } /// [ SRCategory(SR.CatAsynchronous), Localizable(true), RefreshProperties(RefreshProperties.All), SRDescription(SR.PictureBoxInitialImageDescr) ] public Image InitialImage { get { // Strange pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage] approach // used here to avoid statically loading the default bitmaps from resources at // runtime when they're never used. if (initialImage == null && pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage]) { if (defaultInitialImage == null) { // Can't share images across threads. if (defaultInitialImageForThread == null) { defaultInitialImageForThread = new Bitmap(typeof(PictureBox), "PictureBox.Loading.bmp"); } defaultInitialImage = defaultInitialImageForThread; } initialImage = defaultInitialImage; } return initialImage; } set { if (InitialImage != value) { pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage] = false; } initialImage = value; } } private void InstallNewImage(Image value, ImageInstallationType installationType) { StopAnimate(); this.image = value; LayoutTransaction.DoLayoutIf(AutoSize, this, this, PropertyNames.Image); Animate(); if (installationType != ImageInstallationType.ErrorOrInitial) { AdjustSize(); } this.imageInstallationType = installationType; Invalidate(); CommonProperties.xClearPreferredSizeCache(this); } /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public ImeMode ImeMode { get { return base.ImeMode; } set { base.ImeMode = value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler ImeModeChanged { add { base.ImeModeChanged += value; } remove { base.ImeModeChanged -= value; } } /// // Synchronous load [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoad0Descr) ] public void Load() { if (imageLocation == null || imageLocation.Length == 0) { throw new InvalidOperationException(SR.GetString(SR.PictureBoxNoImageLocation)); } // If the load and install fails, pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation] will be // false to prevent subsequent attempts. pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation] = false; Image img; ImageInstallationType installType = ImageInstallationType.FromUrl; try { Uri uri = CalculateUri(imageLocation); if (uri.IsFile) { using (StreamReader reader = new StreamReader(uri.LocalPath)) { img = Image.FromStream(reader.BaseStream); } } else { using (WebClient wc = new WebClient()) { using (Stream s = wc.OpenRead(uri.ToString())) { img = Image.FromStream(s); } } } } catch { if (!DesignMode) { throw; } else { // In design mode, just replace with Error bitmap. img = ErrorImage; installType = ImageInstallationType.ErrorOrInitial; } } InstallNewImage(img, installType); } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoad1Descr), SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings") // PM review done ] public void Load(String url) { this.ImageLocation = url; this.Load(); } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoadAsync0Descr) ] public void LoadAsync() { if (imageLocation == null || imageLocation.Length == 0) { throw new InvalidOperationException(SR.GetString(SR.PictureBoxNoImageLocation)); } if (pictureBoxState[PICTUREBOXSTATE_asyncOperationInProgress]) { //We shouldn't throw here: just return (VSWhidbey 160308). return; } pictureBoxState[PICTUREBOXSTATE_asyncOperationInProgress] = true; if ((Image == null || (imageInstallationType == ImageInstallationType.ErrorOrInitial)) && InitialImage != null) { InstallNewImage(InitialImage, ImageInstallationType.ErrorOrInitial); } currentAsyncLoadOperation = AsyncOperationManager.CreateOperation(null); if (loadCompletedDelegate == null) { loadCompletedDelegate = new SendOrPostCallback(LoadCompletedDelegate); loadProgressDelegate = new SendOrPostCallback(LoadProgressDelegate); readBuffer = new byte[readBlockSize]; } pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation] = false; pictureBoxState[PICTUREBOXSTATE_cancellationPending] = false; contentLength = -1; tempDownloadStream = new MemoryStream(); WebRequest req = WebRequest.Create(CalculateUri(imageLocation)); // Invoke BeginGetResponse on a threadpool thread, as it has // unpredictable latency, since, on first call, it may load in the // configuration system (this is NCL bug 20605) (new WaitCallback(BeginGetResponseDelegate)).BeginInvoke(req, null, null); } // Solely for calling BeginGetResponse itself asynchronously. private void BeginGetResponseDelegate(object arg) { WebRequest req = (WebRequest)arg; req.BeginGetResponse(new AsyncCallback(GetResponseCallback), req); } private void PostCompleted(Exception error, bool cancelled) { AsyncOperation temp = currentAsyncLoadOperation; currentAsyncLoadOperation = null; if (temp != null) { temp.PostOperationCompleted( loadCompletedDelegate, new AsyncCompletedEventArgs(error, cancelled, null)); } } private void LoadCompletedDelegate(object arg) { AsyncCompletedEventArgs e = (AsyncCompletedEventArgs)arg; Image img = ErrorImage; ImageInstallationType installType = ImageInstallationType.ErrorOrInitial; if (!e.Cancelled && e.Error == null) { // successful completion try { img = Image.FromStream(tempDownloadStream); installType = ImageInstallationType.FromUrl; } catch (Exception error) { e = new AsyncCompletedEventArgs(error, false, null); } } // If cancelled, don't change the image if (!e.Cancelled) { InstallNewImage(img, installType); } tempDownloadStream = null; pictureBoxState[PICTUREBOXSTATE_cancellationPending] = false; pictureBoxState[PICTUREBOXSTATE_asyncOperationInProgress] = false; OnLoadCompleted(e); } private void LoadProgressDelegate(object arg) { OnLoadProgressChanged((ProgressChangedEventArgs)arg); } private void GetResponseCallback(IAsyncResult result) { if (pictureBoxState[PICTUREBOXSTATE_cancellationPending]) { PostCompleted(null, true); } else { try { WebRequest req = (WebRequest)result.AsyncState; WebResponse webResponse = req.EndGetResponse(result); contentLength = (int)webResponse.ContentLength; totalBytesRead = 0; Stream responseStream = webResponse.GetResponseStream(); // Continue on with asynchronous reading. responseStream.BeginRead( readBuffer, 0, readBlockSize, new AsyncCallback(ReadCallBack), responseStream); } catch (Exception error) { // Since this is on a non-UI thread, we catch any exceptions and // pass them back as data to the UI-thread. PostCompleted(error, false); } } } private void ReadCallBack(IAsyncResult result) { if (pictureBoxState[PICTUREBOXSTATE_cancellationPending]) { PostCompleted(null, true); } else { Stream responseStream = (Stream)result.AsyncState; try { int bytesRead = responseStream.EndRead(result); if (bytesRead > 0) { totalBytesRead += bytesRead; tempDownloadStream.Write(readBuffer, 0, bytesRead); responseStream.BeginRead( readBuffer, 0, readBlockSize, new AsyncCallback(ReadCallBack), responseStream); // Report progress thus far, but only if we know total length. if (contentLength != -1) { int progress = (int)(100 * (((float)totalBytesRead) / ((float)contentLength))); if (currentAsyncLoadOperation != null) { currentAsyncLoadOperation.Post(loadProgressDelegate, new ProgressChangedEventArgs(progress, null)); } } } else { tempDownloadStream.Seek(0, SeekOrigin.Begin); if (currentAsyncLoadOperation != null) { currentAsyncLoadOperation.Post(loadProgressDelegate, new ProgressChangedEventArgs(100, null)); } PostCompleted(null, false); // Do this so any exception that Close() throws will be // dealt with ok. Stream rs = responseStream; responseStream = null; rs.Close(); } } catch (Exception error) { // Since this is on a non-UI thread, we catch any exceptions and // pass them back as data to the UI-thread. PostCompleted(error, false); if (responseStream != null) { responseStream.Close(); } } } } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoadAsync1Descr), SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings") // PM review done ] public void LoadAsync(String url) { this.ImageLocation = url; this.LoadAsync(); } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoadCompletedDescr) ] public event AsyncCompletedEventHandler LoadCompleted { add { this.Events.AddHandler(loadCompletedKey, value); } remove { this.Events.RemoveHandler(loadCompletedKey, value); } } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoadProgressChangedDescr) ] public event ProgressChangedEventHandler LoadProgressChanged { add { this.Events.AddHandler(loadProgressChangedKey, value); } remove { this.Events.RemoveHandler(loadProgressChangedKey, value); } } private void ResetInitialImage() { pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage] = true; initialImage = defaultInitialImage; } private void ResetErrorImage() { pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage] = true; errorImage = defaultErrorImage; } private void ResetImage() { InstallNewImage(null, ImageInstallationType.DirectlySpecified); } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override RightToLeft RightToLeft { get { return base.RightToLeft; } set { base.RightToLeft = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler RightToLeftChanged { add { base.RightToLeftChanged += value; } remove { base.RightToLeftChanged -= value; } } // Be sure not to re-serialized initial image if it's the default. private bool ShouldSerializeInitialImage() { return !pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage]; } // Be sure not to re-serialized error image if it's the default. private bool ShouldSerializeErrorImage() { return !pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage]; } // Be sure not to serialize image if it wasn't directly specified // through the Image property (e.g., if it's a download, or an initial // or error image) private bool ShouldSerializeImage() { return (imageInstallationType == ImageInstallationType.DirectlySpecified) && (Image != null); } /// /// /// [ DefaultValue(PictureBoxSizeMode.Normal), SRCategory(SR.CatBehavior), Localizable(true), SRDescription(SR.PictureBoxSizeModeDescr), RefreshProperties(RefreshProperties.Repaint) ] public PictureBoxSizeMode SizeMode { get { return sizeMode; } set { //valid values are 0x0 to 0x4 if (!ClientUtils.IsEnumValid(value, (int)value, (int)PictureBoxSizeMode.Normal, (int)PictureBoxSizeMode.Zoom)) { throw new InvalidEnumArgumentException("value", (int)value, typeof(PictureBoxSizeMode)); } if (this.sizeMode != value) { if (value == PictureBoxSizeMode.AutoSize) { this.AutoSize = true; SetStyle(ControlStyles.FixedHeight | ControlStyles.FixedWidth, true); } if (value != PictureBoxSizeMode.AutoSize) { this.AutoSize = false; SetStyle(ControlStyles.FixedHeight | ControlStyles.FixedWidth, false); savedSize = Size; } sizeMode = value; AdjustSize(); Invalidate(); OnSizeModeChanged(EventArgs.Empty); } } } private static readonly object EVENT_SIZEMODECHANGED = new object(); ///Indicates how the image is displayed. ////// /// [SRCategory(SR.CatPropertyChanged), SRDescription(SR.PictureBoxOnSizeModeChangedDescr)] public event EventHandler SizeModeChanged { add { Events.AddHandler(EVENT_SIZEMODECHANGED, value); } remove { Events.RemoveHandler(EVENT_SIZEMODECHANGED, value); } } ///[To be supplied.] ////// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public bool TabStop { get { return base.TabStop; } set { base.TabStop = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TabStopChanged { add { base.TabStopChanged += value; } remove { base.TabStopChanged -= value; } } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public int TabIndex { get { return base.TabIndex; } set { base.TabIndex = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TabIndexChanged { add { base.TabIndexChanged += value; } remove { base.TabIndexChanged -= value; } } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Bindable(false)] public override string Text { get { return base.Text; } set { base.Text = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TextChanged { add { base.TextChanged += value; } remove { base.TextChanged -= value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler Enter { add { base.Enter += value; } remove { base.Enter -= value; } } /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event KeyEventHandler KeyUp { add { base.KeyUp += value; } remove { base.KeyUp -= value; } } ///[To be supplied.] ////// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event KeyEventHandler KeyDown { add { base.KeyDown += value; } remove { base.KeyDown -= value; } } ///[To be supplied.] ////// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event KeyPressEventHandler KeyPress { add { base.KeyPress += value; } remove { base.KeyPress -= value; } } ///[To be supplied.] ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler Leave { add { base.Leave += value; } remove { base.Leave -= value; } } /// /// /// If the PictureBox has the SizeMode property set to AutoSize, this makes /// sure that the picturebox is large enough to hold the image. /// ///private void AdjustSize() { if (sizeMode == PictureBoxSizeMode.AutoSize) { Size = PreferredSize; } else { Size = savedSize; } } private void Animate() { Animate(!DesignMode && Visible && Enabled && ParentInternal != null); } private void StopAnimate() { Animate(false); } private void Animate(bool animate) { if (animate != this.currentlyAnimating) { if (animate) { if (this.image != null) { ImageAnimator.Animate(this.image, new EventHandler(this.OnFrameChanged)); this.currentlyAnimating = animate; } } else { if (this.image != null) { ImageAnimator.StopAnimate(this.image, new EventHandler(this.OnFrameChanged)); this.currentlyAnimating = animate; } } } } /// /// /// ///protected override void Dispose(bool disposing) { if (disposing) { StopAnimate(); } base.Dispose(disposing); } // Overriding this method allows us to get the caching and clamping the proposedSize/output to // MinimumSize / MaximumSize from GetPreferredSize for free. internal override Size GetPreferredSizeCore(Size proposedSize) { if (image == null) { return CommonProperties.GetSpecifiedBounds(this).Size; } else { Size bordersAndPadding = SizeFromClientSize(Size.Empty) + Padding.Size; return image.Size + bordersAndPadding; } } /// protected override void OnEnabledChanged(EventArgs e) { base.OnEnabledChanged(e); Animate(); } private void OnFrameChanged(object o, EventArgs e) { if (Disposing || IsDisposed) { return; } // Handle should be created, before calling the BeginInvoke. // refer VsWhidbey : 315136. if (InvokeRequired && IsHandleCreated) { lock (internalSyncObject) { if (handleValid) { BeginInvoke(new EventHandler(this.OnFrameChanged), o, e); } return; } } Invalidate(); } [EditorBrowsable(EditorBrowsableState.Advanced)] protected override void OnHandleDestroyed(EventArgs e) { lock (internalSyncObject) { handleValid = false; } base.OnHandleDestroyed(e); } [EditorBrowsable(EditorBrowsableState.Advanced)] protected override void OnHandleCreated(EventArgs e) { lock (internalSyncObject) { handleValid = true; } base.OnHandleCreated(e); } /// protected virtual void OnLoadCompleted(AsyncCompletedEventArgs e) { AsyncCompletedEventHandler handler = (AsyncCompletedEventHandler)(Events[loadCompletedKey]); if (handler != null) { handler(this, e); } } /// protected virtual void OnLoadProgressChanged(ProgressChangedEventArgs e) { ProgressChangedEventHandler handler = (ProgressChangedEventHandler)(Events[loadProgressChangedKey]); if (handler != null) { handler(this, e); } } /// /// /// Overridden onPaint to make sure that the image is painted correctly. /// ///protected override void OnPaint(PaintEventArgs pe) { if (pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation]) { try { if (WaitOnLoad) { Load(); } else { LoadAsync(); } } catch (Exception ex) { //Dont throw but paint error image LoadAsync fails.... // [....] FXCOP if (ClientUtils.IsCriticalException(ex)) { throw; } image = ErrorImage; } } if (image != null) { Animate(); ImageAnimator.UpdateFrames(); // Error and initial image are drawn centered, non-stretched. Rectangle drawingRect = (imageInstallationType == ImageInstallationType.ErrorOrInitial) ? ImageRectangleFromSizeMode(PictureBoxSizeMode.CenterImage) : ImageRectangle; pe.Graphics.DrawImage(image, drawingRect); } // Windows draws the border for us (see CreateParams) base.OnPaint(pe); // raise Paint event } /// /// /// protected override void OnVisibleChanged(EventArgs e) { base.OnVisibleChanged(e); Animate(); } ///[To be supplied.] ////// /// protected override void OnParentChanged(EventArgs e) { base.OnParentChanged(e); Animate(); } ///[To be supplied.] ////// /// OnResize override to invalidate entire control in Stetch mode /// ///protected override void OnResize(EventArgs e) { base.OnResize(e); if (sizeMode == PictureBoxSizeMode.Zoom || sizeMode == PictureBoxSizeMode.StretchImage || sizeMode == PictureBoxSizeMode.CenterImage || BackgroundImage != null) { Invalidate(); } savedSize = Size; } /// /// /// protected virtual void OnSizeModeChanged(EventArgs e) { EventHandler eh = Events[EVENT_SIZEMODECHANGED] as EventHandler; if (eh != null) { eh(this, e); } } ///[To be supplied.] ////// /// Returns a string representation for this control. /// ///public override string ToString() { string s = base.ToString(); return s + ", SizeMode: " + sizeMode.ToString("G"); } /// [ SRCategory(SR.CatAsynchronous), Localizable(true), DefaultValue(false), SRDescription(SR.PictureBoxWaitOnLoadDescr) ] public bool WaitOnLoad { get { return pictureBoxState[PICTUREBOXSTATE_waitOnLoad]; } set { pictureBoxState[PICTUREBOXSTATE_waitOnLoad] = value; } } private enum ImageInstallationType { DirectlySpecified, ErrorOrInitial, FromUrl } /// /// void ISupportInitialize.BeginInit() { pictureBoxState[PICTUREBOXSTATE_inInitialization] = true; } /// /// void ISupportInitialize.EndInit() { Debug.Assert(pictureBoxState[PICTUREBOXSTATE_inInitialization]); // Need to do this in EndInit since there's no guarantee of the // order in which ImageLocation and WaitOnLoad will be set. if (ImageLocation != null && ImageLocation.Length != 0 && WaitOnLoad) { // Load when initialization completes, so any error will occur synchronously Load(); } pictureBoxState[PICTUREBOXSTATE_inInitialization] = false; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System.Runtime.Serialization.Formatters; using System.Runtime.InteropServices; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System; using System.IO; using System.Security.Permissions; using System.Drawing; using System.Net; using System.ComponentModel; using System.ComponentModel.Design; using System.Threading; using System.Windows.Forms.Layout; using Microsoft.Win32; ////// /// [ ComVisible(true), ClassInterface(ClassInterfaceType.AutoDispatch), DefaultProperty("Image"), DefaultBindingProperty("Image"), Docking(DockingBehavior.Ask), Designer("System.Windows.Forms.Design.PictureBoxDesigner, " + AssemblyRef.SystemDesign), SRDescription(SR.DescriptionPictureBox) ] public class PictureBox : Control, ISupportInitialize { ///Displays an image that can be a graphic from a bitmap, /// icon, or metafile, as well as from /// an enhanced metafile, JPEG, or GIF files. ////// /// The type of border this control will have. /// private BorderStyle borderStyle = System.Windows.Forms.BorderStyle.None; ////// /// The image being displayed. /// private Image image; ////// /// Controls how the image is placed within our bounds, or how we are /// sized to fit said image. /// private PictureBoxSizeMode sizeMode = PictureBoxSizeMode.Normal; private Size savedSize; bool currentlyAnimating; // Instance members for asynchronous behavior private AsyncOperation currentAsyncLoadOperation = null; private string imageLocation; private Image initialImage; private Image errorImage; private int contentLength; private int totalBytesRead; private MemoryStream tempDownloadStream; private const int readBlockSize = 4096; private byte[] readBuffer = null; private ImageInstallationType imageInstallationType; private SendOrPostCallback loadCompletedDelegate = null; private SendOrPostCallback loadProgressDelegate = null; private bool handleValid = false; private object internalSyncObject = new object(); // These default images will be demand loaded. private Image defaultInitialImage = null; private Image defaultErrorImage = null; [ ThreadStatic ] private static Image defaultInitialImageForThread = null; [ ThreadStatic ] private static Image defaultErrorImageForThread = null; private static readonly object defaultInitialImageKey = new object(); private static readonly object defaultErrorImageKey = new object(); private static readonly object loadCompletedKey = new object(); private static readonly object loadProgressChangedKey = new object(); private const int PICTUREBOXSTATE_asyncOperationInProgress = 0x00000001; private const int PICTUREBOXSTATE_cancellationPending = 0x00000002; private const int PICTUREBOXSTATE_useDefaultInitialImage = 0x00000004; private const int PICTUREBOXSTATE_useDefaultErrorImage = 0x00000008; private const int PICTUREBOXSTATE_waitOnLoad = 0x00000010; private const int PICTUREBOXSTATE_needToLoadImageLocation = 0x00000020; private const int PICTUREBOXSTATE_inInitialization = 0x00000040; // PERF: take all the bools and put them into a state variable private System.Collections.Specialized.BitVector32 pictureBoxState; // see PICTUREBOXSTATE_ consts above ////// /// public PictureBox() { // this class overrides GetPreferredSizeCore, let Control automatically cache the result SetState2(STATE2_USEPREFERREDSIZECACHE, true); pictureBoxState = new System.Collections.Specialized.BitVector32(PICTUREBOXSTATE_useDefaultErrorImage | PICTUREBOXSTATE_useDefaultInitialImage); SetStyle(ControlStyles.Opaque |ControlStyles.Selectable , false); SetStyle(ControlStyles.OptimizedDoubleBuffer|ControlStyles.SupportsTransparentBackColor, true); TabStop = false; savedSize = Size; } ///Creates a new picture with all default properties and no /// Image. The default PictureBox.SizeMode will be PictureBoxSizeMode.NORMAL. /// ////// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override bool AllowDrop { get { return base.AllowDrop; } set { base.AllowDrop = value; } } ////// /// [ DefaultValue(BorderStyle.None), SRCategory(SR.CatAppearance), DispId(NativeMethods.ActiveX.DISPID_BORDERSTYLE), SRDescription(SR.PictureBoxBorderStyleDescr) ] public BorderStyle BorderStyle { get { return borderStyle; } set { //valid values are 0x0 to 0x2 if (!ClientUtils.IsEnumValid(value, (int)value, (int)BorderStyle.None, (int)BorderStyle.Fixed3D)){ throw new InvalidEnumArgumentException("value", (int)value, typeof(BorderStyle)); } if (borderStyle != value) { borderStyle = value; RecreateHandle(); AdjustSize(); } } } // Try to build a URI, but if that fails, that means it's a relative // path, and we treat it as relative to the working directory (which is // what GetFullPath uses). private Uri CalculateUri(string path) { Uri uri; try { uri = new Uri(path); } catch (UriFormatException) { // It's a relative pathname, get its full path as a file. path = Path.GetFullPath(path); uri = new Uri(path); } return uri; } ///Indicates the /// border style for the control. ///[ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxCancelAsyncDescr) ] public void CancelAsync() { pictureBoxState[PICTUREBOXSTATE_cancellationPending] = true; } /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new bool CausesValidation { get { return base.CausesValidation; } set { base.CausesValidation = value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler CausesValidationChanged { add { base.CausesValidationChanged += value; } remove { base.CausesValidationChanged -= value; } } /// /// /// /// protected override CreateParams CreateParams { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] get { CreateParams cp = base.CreateParams; switch (borderStyle) { case BorderStyle.Fixed3D: cp.ExStyle |= NativeMethods.WS_EX_CLIENTEDGE; break; case BorderStyle.FixedSingle: cp.Style |= NativeMethods.WS_BORDER; break; } return cp; } } ///Returns the parameters needed to create the handle. Inheriting classes /// can override this to provide extra functionality. They should not, /// however, forget to call base.getCreateParams() first to get the struct /// filled up with the basic info. ///protected override ImeMode DefaultImeMode { get { return ImeMode.Disable; } } /// /// /// Deriving classes can override this to configure a default size for their control. /// This is more efficient than setting the size in the control's constructor. /// protected override Size DefaultSize { get { return new Size(100, 50); } } ///[ SRCategory(SR.CatAsynchronous), Localizable(true), RefreshProperties(RefreshProperties.All), SRDescription(SR.PictureBoxErrorImageDescr) ] public Image ErrorImage { get { // Strange pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage] approach used // here to avoid statically loading the default bitmaps from resources at // runtime when they're never used. if (errorImage == null && pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage]) { if (defaultErrorImage == null) { // Can't share images across threads. if (defaultErrorImageForThread == null) { defaultErrorImageForThread = new Bitmap(typeof(PictureBox), "ImageInError.bmp"); } defaultErrorImage = defaultErrorImageForThread; } errorImage = defaultErrorImage; } return errorImage; } set { if (ErrorImage != value) { pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage] = false; } errorImage = value; } } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override Color ForeColor { get { return base.ForeColor; } set { base.ForeColor = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler ForeColorChanged { add { base.ForeColorChanged += value; } remove { base.ForeColorChanged -= value; } } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override Font Font { get { return base.Font; } set { base.Font = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler FontChanged { add { base.FontChanged += value; } remove { base.FontChanged -= value; } } /// /// /// [ SRCategory(SR.CatAppearance), Localizable(true), Bindable(true), SRDescription(SR.PictureBoxImageDescr) ] public Image Image { get { return image; } set { InstallNewImage(value, ImageInstallationType.DirectlySpecified); } } // The area occupied by the image ///Retrieves the Image that the ///is currently displaying. [ SRCategory(SR.CatAsynchronous), Localizable(true), DefaultValue(null), RefreshProperties(RefreshProperties.All), SRDescription(SR.PictureBoxImageLocationDescr) ] public string ImageLocation { get { return imageLocation; } set { // Reload even if value hasn't changed, since Image itself may // have changed. imageLocation = value; pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation] = !string.IsNullOrEmpty(imageLocation); // Reset main image if it hasn't been directly specified. if (string.IsNullOrEmpty(imageLocation) && imageInstallationType != ImageInstallationType.DirectlySpecified) { InstallNewImage(null, ImageInstallationType.DirectlySpecified); } if (WaitOnLoad && !pictureBoxState[PICTUREBOXSTATE_inInitialization] && !string.IsNullOrEmpty(imageLocation)) { // Load immediately, so any error will occur synchronously Load(); } Invalidate(); } } private Rectangle ImageRectangle { get { return ImageRectangleFromSizeMode(sizeMode); } } private Rectangle ImageRectangleFromSizeMode(PictureBoxSizeMode mode) { Rectangle result = LayoutUtils.DeflateRect(ClientRectangle, Padding); if (image != null) { switch (mode) { case PictureBoxSizeMode.Normal: case PictureBoxSizeMode.AutoSize: // Use image's size rather than client size. result.Size = image.Size; break; case PictureBoxSizeMode.StretchImage: // Do nothing, was initialized to the available dimensions. break; case PictureBoxSizeMode.CenterImage: // Center within the available space. result.X += (result.Width - image.Width) / 2; result.Y += (result.Height - image.Height) / 2; result.Size = image.Size; break; case PictureBoxSizeMode.Zoom: Size imageSize = image.Size; float ratio = Math.Min((float)ClientRectangle.Width / (float)imageSize.Width, (float)ClientRectangle.Height / (float)imageSize.Height); result.Width = (int)(imageSize.Width * ratio); result.Height = (int) (imageSize.Height * ratio); result.X = (ClientRectangle.Width - result.Width) /2; result.Y = (ClientRectangle.Height - result.Height) /2; break; default: Debug.Fail("Unsupported PictureBoxSizeMode value: " + mode); break; } } return result; } /// [ SRCategory(SR.CatAsynchronous), Localizable(true), RefreshProperties(RefreshProperties.All), SRDescription(SR.PictureBoxInitialImageDescr) ] public Image InitialImage { get { // Strange pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage] approach // used here to avoid statically loading the default bitmaps from resources at // runtime when they're never used. if (initialImage == null && pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage]) { if (defaultInitialImage == null) { // Can't share images across threads. if (defaultInitialImageForThread == null) { defaultInitialImageForThread = new Bitmap(typeof(PictureBox), "PictureBox.Loading.bmp"); } defaultInitialImage = defaultInitialImageForThread; } initialImage = defaultInitialImage; } return initialImage; } set { if (InitialImage != value) { pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage] = false; } initialImage = value; } } private void InstallNewImage(Image value, ImageInstallationType installationType) { StopAnimate(); this.image = value; LayoutTransaction.DoLayoutIf(AutoSize, this, this, PropertyNames.Image); Animate(); if (installationType != ImageInstallationType.ErrorOrInitial) { AdjustSize(); } this.imageInstallationType = installationType; Invalidate(); CommonProperties.xClearPreferredSizeCache(this); } /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public ImeMode ImeMode { get { return base.ImeMode; } set { base.ImeMode = value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler ImeModeChanged { add { base.ImeModeChanged += value; } remove { base.ImeModeChanged -= value; } } /// // Synchronous load [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoad0Descr) ] public void Load() { if (imageLocation == null || imageLocation.Length == 0) { throw new InvalidOperationException(SR.GetString(SR.PictureBoxNoImageLocation)); } // If the load and install fails, pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation] will be // false to prevent subsequent attempts. pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation] = false; Image img; ImageInstallationType installType = ImageInstallationType.FromUrl; try { Uri uri = CalculateUri(imageLocation); if (uri.IsFile) { using (StreamReader reader = new StreamReader(uri.LocalPath)) { img = Image.FromStream(reader.BaseStream); } } else { using (WebClient wc = new WebClient()) { using (Stream s = wc.OpenRead(uri.ToString())) { img = Image.FromStream(s); } } } } catch { if (!DesignMode) { throw; } else { // In design mode, just replace with Error bitmap. img = ErrorImage; installType = ImageInstallationType.ErrorOrInitial; } } InstallNewImage(img, installType); } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoad1Descr), SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings") // PM review done ] public void Load(String url) { this.ImageLocation = url; this.Load(); } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoadAsync0Descr) ] public void LoadAsync() { if (imageLocation == null || imageLocation.Length == 0) { throw new InvalidOperationException(SR.GetString(SR.PictureBoxNoImageLocation)); } if (pictureBoxState[PICTUREBOXSTATE_asyncOperationInProgress]) { //We shouldn't throw here: just return (VSWhidbey 160308). return; } pictureBoxState[PICTUREBOXSTATE_asyncOperationInProgress] = true; if ((Image == null || (imageInstallationType == ImageInstallationType.ErrorOrInitial)) && InitialImage != null) { InstallNewImage(InitialImage, ImageInstallationType.ErrorOrInitial); } currentAsyncLoadOperation = AsyncOperationManager.CreateOperation(null); if (loadCompletedDelegate == null) { loadCompletedDelegate = new SendOrPostCallback(LoadCompletedDelegate); loadProgressDelegate = new SendOrPostCallback(LoadProgressDelegate); readBuffer = new byte[readBlockSize]; } pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation] = false; pictureBoxState[PICTUREBOXSTATE_cancellationPending] = false; contentLength = -1; tempDownloadStream = new MemoryStream(); WebRequest req = WebRequest.Create(CalculateUri(imageLocation)); // Invoke BeginGetResponse on a threadpool thread, as it has // unpredictable latency, since, on first call, it may load in the // configuration system (this is NCL bug 20605) (new WaitCallback(BeginGetResponseDelegate)).BeginInvoke(req, null, null); } // Solely for calling BeginGetResponse itself asynchronously. private void BeginGetResponseDelegate(object arg) { WebRequest req = (WebRequest)arg; req.BeginGetResponse(new AsyncCallback(GetResponseCallback), req); } private void PostCompleted(Exception error, bool cancelled) { AsyncOperation temp = currentAsyncLoadOperation; currentAsyncLoadOperation = null; if (temp != null) { temp.PostOperationCompleted( loadCompletedDelegate, new AsyncCompletedEventArgs(error, cancelled, null)); } } private void LoadCompletedDelegate(object arg) { AsyncCompletedEventArgs e = (AsyncCompletedEventArgs)arg; Image img = ErrorImage; ImageInstallationType installType = ImageInstallationType.ErrorOrInitial; if (!e.Cancelled && e.Error == null) { // successful completion try { img = Image.FromStream(tempDownloadStream); installType = ImageInstallationType.FromUrl; } catch (Exception error) { e = new AsyncCompletedEventArgs(error, false, null); } } // If cancelled, don't change the image if (!e.Cancelled) { InstallNewImage(img, installType); } tempDownloadStream = null; pictureBoxState[PICTUREBOXSTATE_cancellationPending] = false; pictureBoxState[PICTUREBOXSTATE_asyncOperationInProgress] = false; OnLoadCompleted(e); } private void LoadProgressDelegate(object arg) { OnLoadProgressChanged((ProgressChangedEventArgs)arg); } private void GetResponseCallback(IAsyncResult result) { if (pictureBoxState[PICTUREBOXSTATE_cancellationPending]) { PostCompleted(null, true); } else { try { WebRequest req = (WebRequest)result.AsyncState; WebResponse webResponse = req.EndGetResponse(result); contentLength = (int)webResponse.ContentLength; totalBytesRead = 0; Stream responseStream = webResponse.GetResponseStream(); // Continue on with asynchronous reading. responseStream.BeginRead( readBuffer, 0, readBlockSize, new AsyncCallback(ReadCallBack), responseStream); } catch (Exception error) { // Since this is on a non-UI thread, we catch any exceptions and // pass them back as data to the UI-thread. PostCompleted(error, false); } } } private void ReadCallBack(IAsyncResult result) { if (pictureBoxState[PICTUREBOXSTATE_cancellationPending]) { PostCompleted(null, true); } else { Stream responseStream = (Stream)result.AsyncState; try { int bytesRead = responseStream.EndRead(result); if (bytesRead > 0) { totalBytesRead += bytesRead; tempDownloadStream.Write(readBuffer, 0, bytesRead); responseStream.BeginRead( readBuffer, 0, readBlockSize, new AsyncCallback(ReadCallBack), responseStream); // Report progress thus far, but only if we know total length. if (contentLength != -1) { int progress = (int)(100 * (((float)totalBytesRead) / ((float)contentLength))); if (currentAsyncLoadOperation != null) { currentAsyncLoadOperation.Post(loadProgressDelegate, new ProgressChangedEventArgs(progress, null)); } } } else { tempDownloadStream.Seek(0, SeekOrigin.Begin); if (currentAsyncLoadOperation != null) { currentAsyncLoadOperation.Post(loadProgressDelegate, new ProgressChangedEventArgs(100, null)); } PostCompleted(null, false); // Do this so any exception that Close() throws will be // dealt with ok. Stream rs = responseStream; responseStream = null; rs.Close(); } } catch (Exception error) { // Since this is on a non-UI thread, we catch any exceptions and // pass them back as data to the UI-thread. PostCompleted(error, false); if (responseStream != null) { responseStream.Close(); } } } } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoadAsync1Descr), SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings") // PM review done ] public void LoadAsync(String url) { this.ImageLocation = url; this.LoadAsync(); } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoadCompletedDescr) ] public event AsyncCompletedEventHandler LoadCompleted { add { this.Events.AddHandler(loadCompletedKey, value); } remove { this.Events.RemoveHandler(loadCompletedKey, value); } } /// [ SRCategory(SR.CatAsynchronous), SRDescription(SR.PictureBoxLoadProgressChangedDescr) ] public event ProgressChangedEventHandler LoadProgressChanged { add { this.Events.AddHandler(loadProgressChangedKey, value); } remove { this.Events.RemoveHandler(loadProgressChangedKey, value); } } private void ResetInitialImage() { pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage] = true; initialImage = defaultInitialImage; } private void ResetErrorImage() { pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage] = true; errorImage = defaultErrorImage; } private void ResetImage() { InstallNewImage(null, ImageInstallationType.DirectlySpecified); } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override RightToLeft RightToLeft { get { return base.RightToLeft; } set { base.RightToLeft = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler RightToLeftChanged { add { base.RightToLeftChanged += value; } remove { base.RightToLeftChanged -= value; } } // Be sure not to re-serialized initial image if it's the default. private bool ShouldSerializeInitialImage() { return !pictureBoxState[PICTUREBOXSTATE_useDefaultInitialImage]; } // Be sure not to re-serialized error image if it's the default. private bool ShouldSerializeErrorImage() { return !pictureBoxState[PICTUREBOXSTATE_useDefaultErrorImage]; } // Be sure not to serialize image if it wasn't directly specified // through the Image property (e.g., if it's a download, or an initial // or error image) private bool ShouldSerializeImage() { return (imageInstallationType == ImageInstallationType.DirectlySpecified) && (Image != null); } /// /// /// [ DefaultValue(PictureBoxSizeMode.Normal), SRCategory(SR.CatBehavior), Localizable(true), SRDescription(SR.PictureBoxSizeModeDescr), RefreshProperties(RefreshProperties.Repaint) ] public PictureBoxSizeMode SizeMode { get { return sizeMode; } set { //valid values are 0x0 to 0x4 if (!ClientUtils.IsEnumValid(value, (int)value, (int)PictureBoxSizeMode.Normal, (int)PictureBoxSizeMode.Zoom)) { throw new InvalidEnumArgumentException("value", (int)value, typeof(PictureBoxSizeMode)); } if (this.sizeMode != value) { if (value == PictureBoxSizeMode.AutoSize) { this.AutoSize = true; SetStyle(ControlStyles.FixedHeight | ControlStyles.FixedWidth, true); } if (value != PictureBoxSizeMode.AutoSize) { this.AutoSize = false; SetStyle(ControlStyles.FixedHeight | ControlStyles.FixedWidth, false); savedSize = Size; } sizeMode = value; AdjustSize(); Invalidate(); OnSizeModeChanged(EventArgs.Empty); } } } private static readonly object EVENT_SIZEMODECHANGED = new object(); ///Indicates how the image is displayed. ////// /// [SRCategory(SR.CatPropertyChanged), SRDescription(SR.PictureBoxOnSizeModeChangedDescr)] public event EventHandler SizeModeChanged { add { Events.AddHandler(EVENT_SIZEMODECHANGED, value); } remove { Events.RemoveHandler(EVENT_SIZEMODECHANGED, value); } } ///[To be supplied.] ////// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public bool TabStop { get { return base.TabStop; } set { base.TabStop = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TabStopChanged { add { base.TabStopChanged += value; } remove { base.TabStopChanged -= value; } } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public int TabIndex { get { return base.TabIndex; } set { base.TabIndex = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TabIndexChanged { add { base.TabIndexChanged += value; } remove { base.TabIndexChanged -= value; } } /// /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Bindable(false)] public override string Text { get { return base.Text; } set { base.Text = value; } } ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TextChanged { add { base.TextChanged += value; } remove { base.TextChanged -= value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler Enter { add { base.Enter += value; } remove { base.Enter -= value; } } /// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event KeyEventHandler KeyUp { add { base.KeyUp += value; } remove { base.KeyUp -= value; } } ///[To be supplied.] ////// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event KeyEventHandler KeyDown { add { base.KeyDown += value; } remove { base.KeyDown -= value; } } ///[To be supplied.] ////// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event KeyPressEventHandler KeyPress { add { base.KeyPress += value; } remove { base.KeyPress -= value; } } ///[To be supplied.] ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler Leave { add { base.Leave += value; } remove { base.Leave -= value; } } /// /// /// If the PictureBox has the SizeMode property set to AutoSize, this makes /// sure that the picturebox is large enough to hold the image. /// ///private void AdjustSize() { if (sizeMode == PictureBoxSizeMode.AutoSize) { Size = PreferredSize; } else { Size = savedSize; } } private void Animate() { Animate(!DesignMode && Visible && Enabled && ParentInternal != null); } private void StopAnimate() { Animate(false); } private void Animate(bool animate) { if (animate != this.currentlyAnimating) { if (animate) { if (this.image != null) { ImageAnimator.Animate(this.image, new EventHandler(this.OnFrameChanged)); this.currentlyAnimating = animate; } } else { if (this.image != null) { ImageAnimator.StopAnimate(this.image, new EventHandler(this.OnFrameChanged)); this.currentlyAnimating = animate; } } } } /// /// /// ///protected override void Dispose(bool disposing) { if (disposing) { StopAnimate(); } base.Dispose(disposing); } // Overriding this method allows us to get the caching and clamping the proposedSize/output to // MinimumSize / MaximumSize from GetPreferredSize for free. internal override Size GetPreferredSizeCore(Size proposedSize) { if (image == null) { return CommonProperties.GetSpecifiedBounds(this).Size; } else { Size bordersAndPadding = SizeFromClientSize(Size.Empty) + Padding.Size; return image.Size + bordersAndPadding; } } /// protected override void OnEnabledChanged(EventArgs e) { base.OnEnabledChanged(e); Animate(); } private void OnFrameChanged(object o, EventArgs e) { if (Disposing || IsDisposed) { return; } // Handle should be created, before calling the BeginInvoke. // refer VsWhidbey : 315136. if (InvokeRequired && IsHandleCreated) { lock (internalSyncObject) { if (handleValid) { BeginInvoke(new EventHandler(this.OnFrameChanged), o, e); } return; } } Invalidate(); } [EditorBrowsable(EditorBrowsableState.Advanced)] protected override void OnHandleDestroyed(EventArgs e) { lock (internalSyncObject) { handleValid = false; } base.OnHandleDestroyed(e); } [EditorBrowsable(EditorBrowsableState.Advanced)] protected override void OnHandleCreated(EventArgs e) { lock (internalSyncObject) { handleValid = true; } base.OnHandleCreated(e); } /// protected virtual void OnLoadCompleted(AsyncCompletedEventArgs e) { AsyncCompletedEventHandler handler = (AsyncCompletedEventHandler)(Events[loadCompletedKey]); if (handler != null) { handler(this, e); } } /// protected virtual void OnLoadProgressChanged(ProgressChangedEventArgs e) { ProgressChangedEventHandler handler = (ProgressChangedEventHandler)(Events[loadProgressChangedKey]); if (handler != null) { handler(this, e); } } /// /// /// Overridden onPaint to make sure that the image is painted correctly. /// ///protected override void OnPaint(PaintEventArgs pe) { if (pictureBoxState[PICTUREBOXSTATE_needToLoadImageLocation]) { try { if (WaitOnLoad) { Load(); } else { LoadAsync(); } } catch (Exception ex) { //Dont throw but paint error image LoadAsync fails.... // [....] FXCOP if (ClientUtils.IsCriticalException(ex)) { throw; } image = ErrorImage; } } if (image != null) { Animate(); ImageAnimator.UpdateFrames(); // Error and initial image are drawn centered, non-stretched. Rectangle drawingRect = (imageInstallationType == ImageInstallationType.ErrorOrInitial) ? ImageRectangleFromSizeMode(PictureBoxSizeMode.CenterImage) : ImageRectangle; pe.Graphics.DrawImage(image, drawingRect); } // Windows draws the border for us (see CreateParams) base.OnPaint(pe); // raise Paint event } /// /// /// protected override void OnVisibleChanged(EventArgs e) { base.OnVisibleChanged(e); Animate(); } ///[To be supplied.] ////// /// protected override void OnParentChanged(EventArgs e) { base.OnParentChanged(e); Animate(); } ///[To be supplied.] ////// /// OnResize override to invalidate entire control in Stetch mode /// ///protected override void OnResize(EventArgs e) { base.OnResize(e); if (sizeMode == PictureBoxSizeMode.Zoom || sizeMode == PictureBoxSizeMode.StretchImage || sizeMode == PictureBoxSizeMode.CenterImage || BackgroundImage != null) { Invalidate(); } savedSize = Size; } /// /// /// protected virtual void OnSizeModeChanged(EventArgs e) { EventHandler eh = Events[EVENT_SIZEMODECHANGED] as EventHandler; if (eh != null) { eh(this, e); } } ///[To be supplied.] ////// /// Returns a string representation for this control. /// ///public override string ToString() { string s = base.ToString(); return s + ", SizeMode: " + sizeMode.ToString("G"); } /// [ SRCategory(SR.CatAsynchronous), Localizable(true), DefaultValue(false), SRDescription(SR.PictureBoxWaitOnLoadDescr) ] public bool WaitOnLoad { get { return pictureBoxState[PICTUREBOXSTATE_waitOnLoad]; } set { pictureBoxState[PICTUREBOXSTATE_waitOnLoad] = value; } } private enum ImageInstallationType { DirectlySpecified, ErrorOrInitial, FromUrl } /// /// void ISupportInitialize.BeginInit() { pictureBoxState[PICTUREBOXSTATE_inInitialization] = true; } /// /// void ISupportInitialize.EndInit() { Debug.Assert(pictureBoxState[PICTUREBOXSTATE_inInitialization]); // Need to do this in EndInit since there's no guarantee of the // order in which ImageLocation and WaitOnLoad will be set. if (ImageLocation != null && ImageLocation.Length != 0 && WaitOnLoad) { // Load when initialization completes, so any error will occur synchronously Load(); } pictureBoxState[PICTUREBOXSTATE_inInitialization] = false; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WCFModelStrings.Designer.cs
- PhoneCallDesigner.cs
- BrowserInteropHelper.cs
- TypeSource.cs
- SparseMemoryStream.cs
- FixedSOMTable.cs
- CodeCastExpression.cs
- ExpressionEditorAttribute.cs
- ImageListDesigner.cs
- Encoder.cs
- DataServiceEntityAttribute.cs
- ConditionalAttribute.cs
- ZipIOExtraFieldElement.cs
- MenuItemStyle.cs
- MissingMemberException.cs
- CodeFieldReferenceExpression.cs
- DnsPermission.cs
- CodeArrayIndexerExpression.cs
- PropertyPathConverter.cs
- WindowsButton.cs
- PrintPreviewControl.cs
- DataRecordInfo.cs
- ThreadStartException.cs
- UpdatePanelControlTrigger.cs
- Vector.cs
- UIElementParaClient.cs
- EntityClassGenerator.cs
- MobileTemplatedControlDesigner.cs
- HttpContext.cs
- PassportAuthentication.cs
- SoapSchemaMember.cs
- ItemDragEvent.cs
- ListViewItem.cs
- ToolboxComponentsCreatingEventArgs.cs
- TreeNode.cs
- DispatcherTimer.cs
- SchemaImporterExtensionElementCollection.cs
- TextViewDesigner.cs
- LoginName.cs
- HashStream.cs
- WebPageTraceListener.cs
- ManagedIStream.cs
- CodeDomConfigurationHandler.cs
- ArgumentsParser.cs
- TypeBuilderInstantiation.cs
- XpsPartBase.cs
- PropertyCollection.cs
- PeerService.cs
- X509PeerCertificateAuthentication.cs
- ALinqExpressionVisitor.cs
- CookielessData.cs
- DeviceContext.cs
- SortAction.cs
- TableParaClient.cs
- SrgsText.cs
- ClientFormsAuthenticationCredentials.cs
- IDataContractSurrogate.cs
- SupportsPreviewControlAttribute.cs
- Line.cs
- ValidationEventArgs.cs
- MinMaxParagraphWidth.cs
- StateChangeEvent.cs
- SafeTimerHandle.cs
- NavigationEventArgs.cs
- CancellationState.cs
- ToolStripDropTargetManager.cs
- ConnectionPoolManager.cs
- ListViewGroupItemCollection.cs
- ReadOnlyAttribute.cs
- XmlExceptionHelper.cs
- BaseHashHelper.cs
- XPathNodeHelper.cs
- DnsPermission.cs
- ConnectionsZone.cs
- AutomationPropertyInfo.cs
- ImageCodecInfoPrivate.cs
- ColorInterpolationModeValidation.cs
- Enlistment.cs
- WindowsRebar.cs
- Soap.cs
- IPipelineRuntime.cs
- RecordsAffectedEventArgs.cs
- ExpressionQuoter.cs
- WindowsTab.cs
- Collection.cs
- NonValidatingSecurityTokenAuthenticator.cs
- Size3D.cs
- ContainerVisual.cs
- MetaColumn.cs
- CodeExporter.cs
- AutoCompleteStringCollection.cs
- MsmqIntegrationChannelListener.cs
- ExternalException.cs
- FrameworkContextData.cs
- WebBrowserDocumentCompletedEventHandler.cs
- DataBoundControlActionList.cs
- _SSPISessionCache.cs
- MessagePropertyDescription.cs
- InitializationEventAttribute.cs
- ItemType.cs