Home
Photo Album
Demos / Downloads
Contact
 
Login
 
 
Changing Themes Dynamically In Asp.net 2.0 May : 08 : 08
Posted by Joshua Folkerts under Rants and Raves  |  May : 08 : 08  |  1 Comments  |  Viewed 329 Times
Time after time i respond on the asp.net with questions in regards to changing a site's theme dynamically.  It is really quite simple to do but there are some steps that need to be taken in order to make it function properly.

What some don't realize is that a page theme can only be set in the Page_PreInit.  Meaning that the page will only grab the theme before all controls and page items are rendered.  If you do it in the page load, as most of you might have known, will cause errors.  So in the following example, i will code up some site that demonstrates how to change a pages theme dynmaically in use with the profile provider.  You may set the pages theme in a session variable or a cookie depending on your preference.  So lets take a look at how we proceed in doing his simple task.

First we are going to create a new website and add the themes folder to the site by:
  1. Right Click on Website Folder
  2. Add ASP.Net Folder
  3. SELECT ->Theme

Do this twice and add how ever many themes you wish to have.
Once we have 2 or how ever many, what we are going to do is add a new Class File to Our Application. Let go ahead and name it BASEPAGE.  Our BASEPAGE is going to handle the Pre-Init for our Theme settings for each page.  Once we have created our Base Page, we need to modify where this page derives from.  We are going to set this to Page.  Page is part of the System.Web.UI Namespace.  One thing to remember is that when you derive a page from lets say our Base Page, this will be handled first, then our normal page will then render.  So for our Base Page, the code should look as follows.

Ref 1
BasePage.cs (Located In App_Code Folder by Default)
-----------------------
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

public class BasePage : Page  // Note that BasePage Derives from System.Web.UI.Page

    protected void Page_PreInit(object sender, EventArgs e) 
    { 
        ProfileCommon pc = HttpContext.Current.Profile as ProfileCommon; 
        Page.Theme = pc.Themes; 

        Page.Theme = Session["UserTheme"];  // Use this if you choose not to use profiles
    }
}

Once we have our BASEPAGE Set up we can move to our Page that will handle the themes.  I chose to use the Master page to use for the user to select which theme they want to use.

So lets add a masterpage.  Remember that we need to derive Default.aspx and all subsequent pages from the Masterpage.  This is pretty self explanitory so I won't go into how to do that.

Okay, Now that we have that, lets go into to masterpage.master and drop a dropdown list onto the form.  This dropdownlist will be used to let the user select which theme they chose to use.  We are going to create a simple DataTable to bind the Dropdownlist too that way, you will not have to manually add a new theme when one is created.  So.  once we dropped the dropdownlist on the page, lets go into the code behind and add some code.

Before the Page_Load Event we are going to want to import the Systems.IO namespace so we can hook up with the themes directory and grab all the themes that are available to us. 

Ref 2
using System.IO;

So now that we have that imported lets Create a DataTable to store our Themes in.

Ref 3
private DataTable dtThemes()

    DataTable dt = new DataTable(); 
    try 
    { 
        dt.Clear(); 
        dt.Columns.Add("Theme", typeof(String)); 
        DirectoryInfo dInfo = new DirectoryInfo(Server.MapPath("App_Themes")); 
        DirectoryInfo[] dArrInfo = dInfo.GetDirectories(); 
        
        foreach (DirectoryInfo sDirectory in dArrInfo) 
        { 
            DataRow row = dt.NewRow(); 
            row["Theme"] = sDirectory.Name; 
            dt.Rows.Add(row); 
        } 
    } 
    catch (Exception ex) 
    { 
    } 
    return dt;
}

So what we just accomplished was we created a Datatable to and mapped our Themes folder to the DIRECTORYINFO class so it will allow us to iterate through the folders.  For each file in the directory, it will add the foldername to the datatable.  At this point, if we run our application, it will not display anything since we haven't tied our datatable to the dropdown.  So, let just go ahead and do that.

Ref 4
protected void Page_Load(object sender, EventArgs e)

    if (!IsPostBack) 
    { 
        ddlTheme.DataSource = dtThemes(); 
        ddlTheme.DataBind(); 
        ddlTheme.SelectedValue = Profile.Themes;
        ddlTheme.SelectedValue = Session["UserTheme"].ToString();  // If using Session For Themes
    }
}

Okay, lets take a look at this.  On the page_load.  If the page is not posting back, it is going to reference the dtThemes() function and fills the datatable.  We set the dropdownlist's datasource to the datatable and binds the data to fill the dropdownlist.  Once we have the dropdown list filled, we set the selected value to the session or profile or cookie, whichever you choose.

We will Now need to add a New File To the application Called Global.asax.  Once we have that added, Add the following Line of Code in the Session_Start Section.  Use the default theme that you are going to choose.  Which reminds me that in the web.config file, you must set a default page theme.

Ref 5
Global.asax
---------------------
void Session_Start(object sender, EventArgs e)

    Session["UserTheme"] = "Blue";  // Only neededif using session
}


web.config
---------------
<pages theme="Blue">

Now that we have the sections added to the web.config file and the global.asax file, we need to program the dropdownlist's selected index changed event argument.  What we need to do is add the following code to the dropdownlist control in the master page and then handle the event of the dropdownlist.  so in its entirety, here is the code for the dropdown list on the master page and the event code for the selectedindexchange of the dropdownlist

Ref 6
Masterpage File
-------------------------
<asp:DropDownList runat="server" ID="ddlTheme" DataTextField="Theme" OnSelectedIndexChanged="ddlTheme_OnSelectedIndexChanged" AutoPostBack="true"/>

Code Behind of Master Page
----------------------------------
protected void ddlTheme_OnSelectedIndexChanged(object sender, EventArgs e)

    Profile.Themes = ddlTheme.SelectedValue; 
    Session["UserTheme"] = ddlTheme.SelectedValue;  //for session based
    Server.Transfer(Request.FilePath);
}

So, now we are almost done.  The last step is to derive the default.aspx page from the BasePage.  The Following line of code is all that we need to wrap this project up.

Ref 7
Complete Default.aspx.cs Code
----------------------------------
public partial class _Default : BasePage   <- Default now derives from Base Page

    protected void Page_Load(object sender, EventArgs e) 
    { 
        Label1.Text = Session["UserTheme"].ToString(); //Just a check to see if it is working
    }
}

If  you found this article difficult to understand, please download the sample app in which I used to create this tutorial.

You can download it HERE

Create Thumbnails With GDI+ And FileUpload Control May : 07 : 08
Posted by Joshua Folkerts under Web Development  |  May : 07 : 08  |  2 Comments  |  Viewed 274 Times
I have read alot of articles that discuss creating thumbnails and it seems like alot of these articles are using third party components to create thumbnails while uploading files.  To think that this is a difficult chore is not as hard as you think it might be.  The following article will set you through setting up your web form to create a thumbnail of your size choice.  For those who are unfamiliar with GDI, GDI is responsible for tasks such as drawing lines and curves, rendering fonts and handling palettes.  We are going to put this subsystem together with ASP.NET 2.0 and render graphics(thumbnails) for use on your site.  You can bypass the tutorial by Downloading the Code HERE

To start, we are going to create a new webform and drag a FileUpload Control from the visual studio toolbox to the webform and place a button control to the right of the upload control.
Ref 1


As you noticed, I changed the text of the button to "Upload" in which you can choose your choice and preference of words.

Now that we have the form setup, why don't we just add a label under the form to show the status of our upload.  This will generate a generic message such as "File uploaded successfull..."

Double click on the upload button to create an onclick event for the upload button or code it in manually.  Totally up to you.  This will create the onclick event for the button in which we are going to first check to see if the file exist, then upload the file, and last, use the uploaded file to generate the thumbnail and dispose of the uploaded file or keep it as an original. 

Before we start programming our uploading function, we need to import some namespaces to utilize the GDI system.  Namespaces needed for our uploading are as follows:

Ref 2

  1. using System.IO;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.Drawing.Drawing2D

Now that we have our namespaces imported for our app, lets get into the bread and butter of our app.
Under our click event of our button " protected void btnUploadButton_Click(object sender, EventArgs e) "
NOTE: btnUploadButton is the id of my upload button for those who might be confused by the naming convention.

first we are going to start byt checking to see if the upload control has a file to be uploaded.  This is very simple and is as follows:

if(FileUpload1.HasFile)
{
      Code here.....
}
else
{
      lblStatus.Text = "Please Specify A File To Be Uploaded!";
}


Once we check to see if it has a file and is true, then we can proceed to continue with our code or display message in our label stating that no file exists or has been selected.  Once we have that, we are going to do some checking to verify that the file being uploaded is an Image file.  What the following code does is grabs the file name of the file being uploaded and searches the last index of ".".  After the . it checks to see if it matches the files that we stated to be allowed to be uploaded.

Ref 3
protected void btnUploadButton_Click(object sender, EventArgs e)

    if (FileUpload1.HasFile) 
    {
        String savePath = Server.MapPath("Images/"); 
        string fileExt = FileUpload1.FileName; 
        int extIndex = fileExt.LastIndexOf("."); 
        
        if (extIndex != -1) 
        { 
            fileExt = (fileExt.Substring(extIndex + 1)).ToLower(); 
            
            if (fileExt == "jpg" || fileExt == "gif" || fileExt == "png" || fileExt == "tiff") 
            { 
                FileUpload1.SaveAs(savePath + FileUpload1.FileName);
            } 
            else 
            { 
                lblStatus.Text = "Files of .jpg, .gif, .png, .tiff Are Only Accepted"; 
            } 
        } 
        else 
        { 
            lblStatus.Text = "Incorrect File Format"; 
        } 
    }
}

NOTE : Notice the code in orange.  This is where i specified the save path of the file.  The text in green is the actual code used for saving the image to the directory.

Now that we have the file uploaded successfully, we are going to create a sub-function to do our GDI Thumbnailing.  This will give us complete control over how we want our image to be Thumbnailed. So we create a function called "GenerateThumb" that accepts three arguments.  Those arguments are (String FilePath, String fileName, int Width) so it will look something like this

Ref 4
private bool GenerateThumb(String FilePath, String fileName, int Width)
{
    Code will be here...
}

So now we are going to call this function right after we save the original file.  So it will look something along the lines of this.
    FileUpload1.SaveAs(savePath + FileUpload1.FileName);
    GenerateThumb(savePath+FileUpload1.FileName, FileUpload1.FileName, 100);

So what we are doing is passing the filepath to the function to create a Bitmap object so we can manipulate it at will.  This is essential to pass in the correct path so it can use the original image that we just uploaded so it has a BASE to work from.

So lets get to the more complex portion of this.
We are going to create a Bitmap object from the file that we uploaded and set the width and height variables of the bitmap so we can do some calculation so our image does not become distorted and or goal is to create a prefectly resized thumbnail 100 pixels width or 100 pixels high depending on which size is larger.  We do this so the image remains in correct proportion.  This can get tricky so please view this code to understand what we are accomplishing.

Ref 5
int ThumbWidth = 0;
int ThumbHeight = 0;

Bitmap origImg = new Bitmap(FilePath);

if (origImg.Height > origImg.Width)

    ThumbWidth = (int)(origImg.Width * ((float)thumbSize / (float)origImg.Height)); 
    ThumbHeight = thumbSize;
}
else

    ThumbWidth = thumbSize; 
    ThumbHeight = (int)(origImg.Height * ((float)thumbSize / (float)origImg.Width));
}


So depending on which on is bigger, it uses that to set the sizes of the canvas in which we will show you in just a bit.  So now we have the iszes, we are going to create a new filename and the path in which to save the New thumbnail.  There are a million ways to set the filename but for my example, I created a new function to replace the extension and just return the filename without the extension.  I also through a little checker for blank(whitespaces) in the file name and replaces the whitespace with an UNDERSCORE.
Function is as follows.:

Ref 6
private static String replaceFileExtension(string CheckExtention)

    CheckExtention = CheckExtention.Replace(".jpg", ""); 
    CheckExtention = CheckExtention.Replace(".gif", ""); 
    CheckExtention = CheckExtention.Replace(".png", ""); 
    CheckExtention = CheckExtention.Replace(".tiff", ""); 
    CheckExtention = CheckExtention.Replace(".tif", ""); 
    CheckExtention = CheckExtention.Replace(".jpeg", ""); 
    CheckExtention = CheckExtention.Replace(".pdf", ""); 
    CheckExtention = CheckExtention.Replace(".eps", ""); 
    CheckExtention = CheckExtention.Replace(".xls", ""); 
    CheckExtention = CheckExtention.Replace(".doc", ""); 
    CheckExtention = CheckExtention.Replace(".mdf", ""); 
    CheckExtention = CheckExtention.Replace(".wps", ""); 
    CheckExtention = CheckExtention.Replace(".JPG", ""); 
    CheckExtention = CheckExtention.Replace(".GIF", ""); 
    CheckExtention = CheckExtention.Replace(".pPNG", ""); 
    CheckExtention = CheckExtention.Replace(".TIFF", ""); 
    CheckExtention = CheckExtention.Replace(".TIF", ""); 
    CheckExtention = CheckExtention.Replace(".JPEG", ""); 
    CheckExtention = CheckExtention.Replace(".PDF", ""); 
    CheckExtention = CheckExtention.Replace(".EPS", ""); 
    CheckExtention = CheckExtention.Replace(".XLS", ""); 
    CheckExtention = CheckExtention.Replace(".DOC", ""); 
    CheckExtention = CheckExtention.Replace(".MDF", ""); 
    CheckExtention = CheckExtention.Replace(".WPS", ""); 
    //Not an extension but removes whitespaces in the 
    //file name and replaces it with and _! 
    CheckExtention = CheckExtention.Replace(" ", "_"); 
    return CheckExtention;
}


So to put this all in play, (Ref 5) sets the new size of the Thumbnail and now we are going to create the new filename and path to save the thumbnail too.
so after the IF statement we type

String newSavePath = Server.MapPath("Images/" + replaceFileExtension(FileUpload1.FileName) + "_thumb.jpg");

To continue, we are going to create a new Bitmap object that will be our destination bitmap image.  This will be used to set our resolution and size of the new image from the formula we stated in Ref 5. 

Code is as follows:

Ref 7
Bitmap dstImg = new Bitmap(ThumbWidth, ThumbHeight);
dstImg.SetResolution(72, 72);


Now we need to create a graphics object so we can make the Image look "Pretty".  Meaning we set the quality, interpolation, smoothing ect.  Without this, your image will take the pixelated effect and that is not what we are striving for.  So the following piece of code will create a graphics object from the bitmap we created in Ref 7 and set the appropriate modes.  We will also draw the image From the original uploaded image to the canvas with coordinates of 0,0, thumbwidth,thumbheight.  Remember, those come from the formula up above.  once we draw the image, we dispose the image to remove it from memory.

Ref 8 
Graphics g = Graphics.FromImage(dstImg);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;

// Resize the original to the thumb width and height
g.DrawImage(origImg, 0, 0, ThumbWidth, ThumbHeight);
g.Dispose();


Last but not least, we set the encoding to tell it what kind of image we want to save it as and the compression of the image.  By compression, i mean, what quality is the thumb going to be.  We will use 100% compression for this example. 

Ref 9
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 100); // 80% Compression
dstImg.Save(newSavePath, ImageCodecInfo.GetImageEncoders()[1], encoderParameters); // jpg format
dstImg.Dispose();
origImg.Dispose();


As seen above.  We save the new image, dispose the original image and the destination image.

That concludes the tutorial on how to create Thumbnail images with GDI.  Pretty simple.....

ENJOY

Joshua Folkerts

Download Code HERE

Updates For JoshuaFolkerts.com May : 03 : 08
Posted by Joshua Folkerts under Miscellaneous  |  May : 03 : 08  |  0 Comments  |  Viewed 59 Times
As some of you frequent visiters already know, JoshuaFolkerts.com has taken on a new look with some added functionality.  Not that it matters to you but for some of you that might ponder the reason for the change, I thought it would be good to update the site to use some of the technologies that I work with on a daily basis. 

Some of the features that I have added is an ajax Photo Gallery that is built on top of the Ajax platform.  I have converted my blog over to the n-tier technology which you I have noticed has sped up the access time to the individual items.  I also have taken all the demos for the applications under the demos / downloads section for the time being until i get some fo the bugs worked out in them.  I apologize to most of you for this because right now, I don't have time to incorperate all the needs some have wished in the application and fix some of the bugs.  So to save the headaches, i have decided to take them down for the time being.

So, on the other hand, I will continue to use this site like i always do, to explore new and innovated ways to make things work alittle more effeciently and to add alittle more visual asthetics to it. 

NOTE : You still have the ability to download th applications, just not demo them first.  The current demos are fully functional but there might be some bugs that i haven't fixed.  The bugs are mostly due to situations and setups in other viewers enviroments.

Joshua Folkerts.