Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ASP Image Control Enchanced

0.00/5 (No votes)
7 Feb 2009 1  
ASP Image Control Enchanced with help of ScriptControl and javascript.When I've started working as a ASP.NET webdeveloper I was troubled by the

This articles was originally at wiki.asp.net but has now been given a new home on CodeProject. Editing rights for this article has been set at Bronze or above, so please go in and edit and update this article to keep it fresh and relevant.

ASP Image Control Enchanced with help of ScriptControl and javascript.

When I've started working as a ASP.NET webdeveloper I was troubled by the limitations of HTML.

One of such limitation that emerged as a problem later in my work was how to correctly stretch a picture with unknown proportions in an fixed size container (e.g slideshow photo frame, or a grid with photos). You would need to know the correct image dimension of the image in advance to set the correct width or height for the img tag otherwise the images would have wrong proportions or they wouldn't fit in their container (full size).

I decided to fix this problem with javascript. But then the issue was should I make a one time fix or do something more reusable. And I decided that If I could do it reusable I wouldn't ever care about this problem ever again so it was worth a little bit longer development time.

I created an custom control that extends image control and implements IScriptcontrol. It will stretch the image correcltly, it can center the image to it's container and also it can show an loading image when the image is so big it takes a while before it's completly loaded.

This control can easily be used in aspx pages in databindings and it has proven to be so useful for me I've decided to share it to the Asp.net community. It's an extended ImageContol that's also an ScriptControl. 

P.S. important When images are smaller than the container they will still be stretched. This is easy to fix and add to my code but I don't have time to do this now.

<code language="C#" name="myImageControl.cs">

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;


[assembly: System.Web.UI.WebResource("Controls.myImage.js", "text/javascript")]
namespace Controls
{
    /// <summary>

    /// ContainerHeight: the height of the container you wish this photo to adjust too

    /// ContainerWidth: the width of the container you wish this img to adjust too.

    /// HorizontalCentered: set to true if you want the image to be centered horizontally in it's container.

    /// VerticalCentered: set to true if you want the image to be centered vertically in it's container.

    /// LoadImgId: ClientID to an image element on your page with shows a load image (gif animation or something like that). This img is show during the time the real image is being loaded (if it's a real big image)

    /// LoadImgWidth: width of load image (couldn't be bothered to check the size of load image on the fly since this image size is often known in advance, if not set the loading image will not be properly centered in the container).

    /// LoadImgHeight: height of load image.

    /// ImageUrlExt: use this to set an image url for the image.

    /// Important! don't use ImageUrl property instead use ImageUrlExt. The reason is because we need to have to have  control of when the image src property is set on the client!

    /// </summary>

    [ToolboxData("<{0}:myImageControl runat=server></{0}:myImageControl>")]
    public class myImage : Image, INamingContainer, IScriptControl
    {

        int _containerHeight;
        //container height
        public int ContainerHeight
        {
            get { return _containerHeight; }
            set { _containerHeight = value; }
        }

        int _containerWidth;
        //container width
        public int ContainerWidth
        {
            get { return _containerWidth; }
            set { _containerWidth = value; }
        }

        string _imageUrlExt;
        //always use this extended ImageURL than
        public string ImageUrlExt
        {
            get { return _imageUrlExt; }
            set { _imageUrlExt = value; }
        }       

        public override string ImageUrl
        {
            get
            {
                return base.ImageUrl;
            }
            set
            {
                base.ImageUrl = "";
            }
        }

        bool _horizontalCentered;

        public bool HorizontalCentered
        {
            get { return _horizontalCentered; }
            set { _horizontalCentered = value; }
        }

        bool _verticalCentered;

        public bool VerticalCentered
        {
            get { return _verticalCentered; }
            set { _verticalCentered = value; }
        }

        string _loadImgId;

        public string LoadImgId
        {
            get { return _loadImgId; }
            set { _loadImgId = value; }
        }

        int _loadImgHeight;

        public int LoadImgHeight
        {
            get { return _loadImgHeight; }
            set { _loadImgHeight = value; }
        }

        int _loadImgWidth;

        public int LoadImgWidth
        {
            get { return _loadImgWidth; }
            set { _loadImgWidth = value; }
        }


        private ScriptManager _scriptManager = null;

        protected override void OnLoad(EventArgs e)
        {

            _scriptManager = ScriptManager.GetCurrent(this.Page);

            base.OnLoad(e);
        }

        protected override void OnPreRender(EventArgs e)
        {            

            _scriptManager = ScriptManager.GetCurrent(this.Page);
            if (_scriptManager != null)
            {
                _scriptManager.RegisterScriptControl(this);
            }
            else
                throw new ApplicationException("You must have a ScriptManager!");

            base.OnPreRender(e);
        }

        protected override void Render(HtmlTextWriter writer)
        {           
            _scriptManager.RegisterScriptDescriptors(this);

            base.Render(writer);
        }


        #region IScriptControl Members

        public IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            ScriptControlDescriptor descriptor = new ScriptControlDescriptor("Controls.myImage", this.ClientID);
            descriptor.AddProperty("containerWidth", this.ContainerWidth);
            descriptor.AddProperty("containerHeight", this.ContainerHeight);
            descriptor.AddProperty("elementId", this.ClientID);
            descriptor.AddProperty("imageUrl", this.ImageUrlExt);
            descriptor.AddProperty("horizontalCentered", this.HorizontalCentered);
            descriptor.AddProperty("verticalCentered", this.VerticalCentered);            
            if(!string.IsNullOrEmpty(this._loadImgId))
                descriptor.AddElementProperty("loadImg", this._loadImgId);
            descriptor.AddProperty("loadImgWidth", this._loadImgWidth);
            descriptor.AddProperty("loadImgHeight", this._loadImgHeight);

            return new ScriptDescriptor[] { descriptor };
        }

        public IEnumerable<ScriptReference> GetScriptReferences()
        {
            ScriptReference reference = new ScriptReference();
            reference.Path = Page.ClientScript.GetWebResourceUrl(typeof(myImage), "Controls.myImage.js");

            return new ScriptReference[] { reference };
        }

        #endregion
    }
}

</code>

And here comes the javascript: 

<code language="js" src="myImage.js">


Type.registerNamespace('Controls');


Controls.myImage = function(element)

{

    

    Controls.myImage.initializeBase(this, [element]);   

    

    this._containerHeight = 0;

    

    this._containerWidth = 0;

    

    this._horizontalCentered = null;

    

    this._verticalCentered = null;

    

    this._elementId = '';

    

    this._onLoadHandler = null;


    this._imageUrl = '';

    

    this._onClick = null;

    

    this._loadImg = null;

    

    this._loadImgWidth = 0;

    

    this._loadImgHeight = 0;

    

    this._loadImgCopy = null;

 

};


Controls.myImage.prototype =

{


    initialize : function() {

    

        // initialize the base

        Controls.myImage.callBaseMethod(this,'initialize');   

    

        //setup event handler before image starts loading!

        this._onLoadHandler = Function.createDelegate(this,this._OnLoad)

        this._onFocusHandler = function(){};

        

        

        $addHandler(this.get_element(),'load', this._onLoadHandler);

        $addHandler(this.get_element(),'focus', this._onFocusHandler);

                     

        this._LoadImage();

        

    },

    

    _setLoadingImage : function()

    {

        this._removeLoadingImage();

        

        if(this._loadImg && this._imageUrl && this._imageUrl != '')

        {

            var element = $get(this._elementId);            

            this._loadImgCopy = this._loadImg.cloneNode(false);            

            this._loadImgCopy.id = this._elementId+'_loadImgInstance';

            this._loadImgCopy.style.display='';

            this._loadImgCopy.style.visibility ='visible';

            

            var hspace = (this._containerWidth - this._loadImgWidth)/2;            

            this._loadImgCopy.setAttribute('hspace',Math.floor(hspace));

            

            var vspace = (this._containerHeight - this._loadImgHeight)/2;

            this._loadImgCopy.setAttribute('vspace',Math.floor(vspace));

            

            element.parentNode.insertBefore(this._loadImgCopy, element);                               

        }

        

    },

    

    _removeLoadingImage : function()

    {

        if(this._loadImgCopy)

        {

            var element = $get(this._elementId);   

            element.parentNode.removeChild(this._loadImgCopy);

            this._loadImgCopy = null;

        }

    },

    

    _LoadImage : function()

    {    

        this._setLoadingImage();

        this.get_element().src = this._imageUrl;

    

    },


    _OnLoad : function()

    {                                                                                                                

        this._removeLoadingImage();

        this.autoAdjustImage();           

        

    },       

                

    

    autoAdjustImage : function()

    {

        var element = $get(this._elementId);

                

        element.removeAttribute('height');

        element.style.height = 'auto';        

        element.removeAttribute('width');

        element.style.width = 'auto';

        

        var imageBounds = Sys.UI.DomElement.getBounds(element);                                                           

                                                

        var imageDimensionRatio = imageBounds.height / imageBounds.width;               

        

        var containerDimensionRatio = this._containerHeight / this._containerWidth;    

        

        if(this._horizontalCentered)

            element.removeAttribute('hspace');

            

        if(this._verticalCentered)

            element.removeAttribute('vspace');        

        

        if(imageDimensionRatio > containerDimensionRatio)

        {   

        

            element.setAttribute('height', '100%');

            element.style.height = '100%';

            

            if(this._horizontalCentered)

            {            

                        

                var scaleRatio = this._containerHeight / imageBounds.height;

            

                var newWidth = imageBounds.width * scaleRatio;

            

                var leftAdjust = (this._containerWidth - newWidth) / 2;                                   

                        

                element.setAttribute('hspace',leftAdjust);

            }                                                                                               

            

        }    

        else

        {

                                                                                    

            element.setAttribute('width', '100%');

            element.style.width = '100%';  

            

            if(this._verticalCentered)

            {  

            

                var scaleRatio = this._containerWidth / imageBounds.width  ;

            

                var newHeight = imageBounds.height * scaleRatio;

            

                var topAdjust = (this._containerHeight - newHeight) / 2;

            

                element.setAttribute('vspace',topAdjust);

            }                            

            

        }  

    },

    

    add_onClickHandler : function(handler)

    {               

        this.remove_onClickHandler();

         

        this._onClick = handler;

        

        $addHandler($get(this._elementId),'click', this._onClick);        

    },

    

    remove_onClickHandler : function()

    {

        if(this._onClick)

        {            

            $removeHandler($get(this._elementId),'click', this._onClick);

            this._onClick = null;

        }

    },

    

    get_containerHeight : function()

    {

        return this._containerHeight;

    },

    

    set_containerHeight : function(value)

    {

        if(this._containerHeight != value)

        {

            this._containerHeight = value;

        }

    },

    

    get_containerWidth : function()

    {

        return this._containerWidth;

    },

    

    set_containerWidth : function(value)

    {

        if(this._containerWidth != value)

        {

            this._containerWidth = value;

        }

    },

    

    get_elementId : function()

    {

        return this._elementId;

    },

    

    set_elementId : function(value)

    {

        if(this._elementId != value)

        {

            this._elementId = value;

        }

    },

    

    get_imageUrl : function()

    {

        return this._imageUrl;

    },

    

    set_imageUrl : function(value)

    {

        if(this._imageUrl != value)

        {

            this._imageUrl = value;

            this.raisePropertyChanged('imageUrl');

        }

    },

    

    get_horizontalCentered : function()

    {

        return this._horizontalCentered;

    },

    

    set_horizontalCentered : function(value)

    {

        if(this._horizontalCentered != value)

        {

            this._horizontalCentered = value;

            this.raisePropertyChanged('horizontalCentered');

        }

        

    },

    

    get_verticalCentered : function()

    {

        return this._verticalCentered;

    },

    

    set_verticalCentered : function(value)

    {

        if(this._verticalCentered != value)

        {

            this._verticalCentered = value;

            this.raisePropertyChanged('verticalCentered');

        }

        

    },

    

    get_loadImg : function()

    {

        return this._loadImg;

    },

    

    set_loadImg : function(value)

    {

        if(this._loadImg != value)

        {

            this._loadImg = value;

            this.raisePropertyChanged('loadImg');

        }

        

    },

    

    get_loadImgWidth : function()

    {

       return this._loadImgWidth;

    },

    

    set_loadImgWidth : function(value)

    {

        if(this._loadImgWidth != value)

        {

            this._loadImgWidth = value;

            this.raisePropertyChanged('loadImgWidth');

        }

        

    },

        

    get_loadImgHeight : function()

    {

       return this._loadImgHeight;

    },

    

    set_loadImgHeight : function(value)

    {

        if(this._loadImgHeight != value)

        {

            this._loadImgHeight = value;

            this.raisePropertyChanged('loadImgHeight');

        }

        

    }

    


};


//register class

Controls.myImage.registerClass('Controls.myImage',Sys.UI.Control);


if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();

<code>

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here