PictureBox.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / 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; 

    ///  
    ///  
    ///     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.
    /// 
    [
    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 {
 
        /// 
        ///  
        ///     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 
 

        ///  
        /// 
        ///    Creates a new picture with all default properties and no
        ///       Image. The default PictureBox.SizeMode will be PictureBoxSizeMode.NORMAL.
        ///     
        /// 
        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; 
        }

        /// 
        ///  
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public override bool AllowDrop {
            get { 
                return base.AllowDrop;
            }
            set {
                base.AllowDrop = value; 
            }
        } 
 
        /// 
        ///  
        ///     Indicates the
        ///       border style for the control.
        /// 
        [ 
        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; 
        }

        /// 
        [ 
        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; 
            }
        } 

        /// 
        /// 
        ///  
        ///    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 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; 
            } 
        }
 
        /// 
        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;
            } 
        }

        /// 
        ///  
        /// Retrieves the Image that the  is currently displaying.
        ///  
        [ 
        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 
        /// 
        [ 
         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);
        }
 
        /// 
        ///  
        ///    Indicates how the image is displayed. 
        /// 
        [ 
        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();
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [SRCategory(SR.CatPropertyChanged), SRDescription(SR.PictureBoxOnSizeModeChangedDescr)]
        public event EventHandler SizeModeChanged { 
            add { 
                Events.AddHandler(EVENT_SIZEMODECHANGED, value);
            } 

            remove {
                Events.RemoveHandler(EVENT_SIZEMODECHANGED, value);
            } 
        }
 
        ///  
        /// 
        ///  
        /// 
        [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;
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [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; 
            }
        }

        ///  
        /// 
        [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; 
                } 
            }
            if (IsWindowObscured) { 
                StopAnimate();
                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
        }

 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        protected override void OnVisibleChanged(EventArgs e) { 
            base.OnVisibleChanged(e);
            Animate();
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        protected override void OnParentChanged(EventArgs e) { 
            base.OnParentChanged(e);
            Animate();
        }
 
        /// 
        ///  
        ///     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; 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        protected virtual void OnSizeModeChanged(EventArgs e) { 
            EventHandler eh = Events[EVENT_SIZEMODECHANGED] as EventHandler;
            if (eh != null) { 
                eh(this, e); 
            }
        } 

        /// 
        /// 
        ///     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.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK