Wednesday, May 30, 2007

Sample Code Post

I was thinking about C# Tuning and I found out that some days I don't have enough time to write an article and post it but there are lot 's of samples that can be published here and you can get some point over them. So I decided to create a new kind of posts, which I will call it "Sample Code Post".

So I hope these samples can be useful for you and if there was any king of question about these samples you can just comment over the post and then I will answer to your questions.

Tuesday, May 29, 2007

Loading images asynchronously with JavaScripts

Sometime you may want to load a list of data in your web pages. Imagine that every row of your data has an image. So you can use a GridView control in your webpage and create you template. The point that I 'm goint to cover in this post is about how to load the images of your rows asynchronously!

It 's seems great to set a default image for your page that will be shown while the images is loading from the server asynchronously. Because that image is loaded once it will help your page load time. And then after page load completed you will start loading your images from server asynchronously.

Let 's start with creating the GridView control and setting an XML file for it 's datasource by using an XML Datasource object in our form. The source code would be something like this:

<asp:XmlDataSource ID="xmlDataSource1" runat="server" DataFile="~/App_Data/mySource.xml"></asp:XmlDataSource>

<asp:GridView ID="gridView1" runat="Server" AutoGenerateColumns="False" DataSourceID="xmlDataSource1" Enabled="false">
<Columns>
<asp:BoundField DataField="Author" HeaderText="Author" />
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:TemplateField>
<HeaderTemplate>Image</HeaderTemplate>
<ItemTemplate>
<img border="1" src="images/csharptuning.jpg" onError="this.src=csharptuning.jpg" onLoad="GetArticleImage(this,'<%# Eval("ImageUrl")%>');" width="125" height="125"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Notice that for loading the default image in each data row, I 've set the "src" attribute of my image control to a default value like src='csharptuning.jpg'.I have also set something to load the actual images asynchronously after the loading of image controls.

So, first I create a web page which is give me my images dynamically by a QueryString. (I have been explained how to create these kind of pages here).

Then I have to set it to load the actual image after the image control loaded. For this purpose I create a JavaScript function in my page like this:

<script>
function GetArticleImage(img, url)
{
img.onload = null;
img.src = 'GetImages.aspx?fname=' + url;
}

</script>

and then I added onLoad='GetArticleImage(this,<%# DataBinder.EvalContainer.DataItem,"ImageUrl") %>' event on my image control.

Now you can start your page, then you will see that in first seconds you will get a default image for each record, but after some seconds (in my code is 5") you will get the actual result of your images.

You can also download this sample by this link:
http://www.tabatabaei.info/csharpsamples/asyncImages.zip

Monday, May 28, 2007

Background Worker

I 'm going to explain how you can use the C# BackgroundWorker component of System.ComponentModel namespace, in your windows form applications.

BackgroundWorker component gives you a way to run a time-consuming task on a separate thread. Actually it works the same way as the asynchronous delegates, but in asynchronous delegate approach you have to consider some issues about working with your UI elements, because there are running on another thread. In BackgroundWorker marshalling issues are abstracted away with an event-based model.

Now let start working with BackgroundWorker.
First, you need an instance of BackgroundWorker class, no diff you are creating this programmatically or by dragging it onto a form at design time from your Component tab of Toolbox.

Next step is to set the event handlers of you object, and finally you have to call RunWorkerAsync() method.

Whenever you call this method it get a free thread from CLR and fires DoWork event. Now you put your codes (The codes that you want to be executed in another thread) in event handler of DoWork event. If the code completed it will raise an event called RunWorkerCompleted to notify you. It 's important to know that this event is not raised on the new thread instead, it will be raised on main thread of your application.

In many cases you may want to prepare some information (Arguments) for your time-consuming task. So, you can achieve this by passing an object into RunWorkerAsync() method, this object is accessible in your DoWork event as an object with it 's event argument.

The event args of DoWork event is an object of type DoWorkEventArgs.
In this object you have a property called Argument for getting what you have passed in RunWorkerAsync() method. You can use it in your time-consuming task.

Then you may want to have the result of your task in your UI. Again for this purpose you have a property called Result which you can set it in your DoWorkEventArgs. And it will be accessible in your RunWorkerCompletedEventArgs of RunWorkerCompleted event.

BackgroundWorker sample download link:
http://www.tabatabaei.info/csharpsamples/backgroundworker.zip

Thursday, May 24, 2007

Changing the Content Type of a Web Page

Some times we want to get an image dynamically from a ASP .NET web form.
So we just create a web form containing an ImageControl. Then in this form we set a value on Session.

protected void Page_Load(object sender,EventArgs e)
{

// Putting some files path on session
Session["MyValue"] = "myImage.gif";
}


Now I want another web page which is create/load an image depending on the value I 've put in Session. And then I set the ImageUrl of that Image control to my new web page. Like this:


<asp:Image ID="imgDynamic" runat="server" ImageUrl="~/getimages.aspx" />

Notice that ImageUrl have been set to an aspx file!

Now in my GetImages web form I have to decide to create/load the image depending on the value of Session variable. The important point is that the output of this web form is not HTML code, instead I is responding some images. So I have to change the content type of my web page. And finally I have to put my Image to the Response of my web page. For these I just write these lines of code:

protected void Page_Load(object sender, System.EventArgs e)
{
// Create/Load the image from the string value in session
Bitmap b = new Bitmap(Server.MapPath(Request.ApplicationPath) + "\\Images\\" + Session["MyValue"].ToString());

// Change the response headers to output a JPEG image.
this.Response.Clear();
this.Response.ContentType = "image/jpeg";

// Write the image to the response stream in JPEG format.
b.Save(this.Response.OutputStream, ImageFormat.Jpeg);

}

Download the sample code:
http://www.tabatabaei.info/csharpsamples/dynamicImage.zip

Monday, May 21, 2007

Localization in ASP .NET 2.0

I 'm going to explain How to implement multi lingual web forms in ASP .NET 2.0.
Let take it with a sample. Imagine we have a web form which user has to fill their personal information and save it to our database. Now, I want this web page to be multilingual.

So, First I just create a web page that I 'm going to have in English version. The web form name is "MultiLingualWebForm.aspx".

Then I have to add an special ASP .NET folder to my web site. So right click on web site, then Add ASP .NET Folder and choose App_LocalResources.

Now I have to add a new item in this folder like this:
R.C* on App_LocalResources --> Add New Item --> Resource File --> Set the name to "MultiLingualWebForm.aspx.resx"

Now a file will open up in Visual Studio .Net, I just try to add some Items in this Resource file and save the file.



Notice that the first part of name "WelcomeLable" is the Control name on the page, and the second part ".Text" is the property name of the control.

Then create another copy of this file with "MultiLingualWebForm.aspx.fr.resx" name.
The fr is telling that it 's the French version of that file.

And also another copy with name "MultiLingualWebForm.aspx.fa.resx" which fa is the international name of Farsi.


Then change all the values to it 's translation of target language:

Welcome ==> خوش آمديد
and so on...

Now, I 'm going to add some new attributes on my ASP controls. So in each of my Label controls I added a new tag called meta with a resourceKey property like this:


<asp:Label ID="WelcomeLabel" runat="server" Text="Label" meta:resourceKey="WelcomeLabel" ></asp:Label>

I add this to all the other Labels and also for those Buttons on my web form.
And I set two properties of my Page in my page directive.

Culture="auto:en-US" UICulture="auto"

Then I save the web page and run it.
So, to check out is it working or not? While you have your browser open, go to Tools menu then Internet Option, in the opening window go to Languages then add Farsi and French, bring up on of the to the first (it 's setting default language of your browser) then OK and OK again.

Now Refresh you page, you will see the translation of that page to your preferred language. OK That 's all.

Anyway, here is the code of my our sample you can download it.
http://www.tabatabaei.info/csharpsamples/MultiLingualWebForm.zip

ASP.NET 2.0 Data Tutorials

I was browsing ASP .Net : The Official Microsoft ASP .NET 2.0 web site and I found out a link about working with data and ASP. NET 2.0.
It 's really great articles about how to work with data in ASP .NET 2.0 and It cover 's lot of things in ASP .Net.

I strongly suggest you to read this articles if you 're interested in working data intensive web application in ASP. NET 2.0

http://www.asp.net/Learn/DataAccess/#intro

Sunday, May 20, 2007

ScottGu's Blog

I want you to introduce a blog from a Microsoft man.
His is name is Scott Guthrie, and he is General Manager within the Microsoft Developer Division. He runs the development teams that build the following products/technologies:

Common Language Runtime (CLR)
ASP.NET
Silverlight
WPF
IIS 7.0
Commerce Server
.NET Compact Framework
Visual Web Developer
Visual Studio Tools for WPF

You can find too many great tips about ASP .NET and Oracas (new version of Visual Studio) and some other Microsoft Technologies.

http://weblogs.asp.net/scottgu/

Starting new process

In the last post, I explained how to get a list of existing process on local or remote machine.
Now I want to explain how to start a new process in C#.

If you create an object of Process class, you can set some information on StartInfo property of the object to specify what to do when you start the process. In the line below I 'm going to Print a word document in my C# sample:

Process printProcess = new Process();
try
{
OpenFileDialog op = new OpenFileDialog();
op.Filter = "Microsoft Word Document (*.doc)*.doc";
if(op.ShowDialog() == DialogResult.OK)
{

printProcess.StartInfo.FileName = op.FileName;
printProcess.StartInfo.Verb = "Print";
printProcess.StartInfo.CreateNoWindow = true;
printProcess.Start();
}
}
catch(Win32Exception ex)
{

if(e.NativeErrorCode ==2)
MessageBox.Show(e.Message + ". Check the path.");
else if(e.NativeErrorCode == 5)
MessageBox.Show(e.Message + ". You do not have permission to print this file.");
}

Notice that I 've used "Print" for Verb property of StartInfo. If you don't know what are available verbs on a extension (if it 's not executable) you can get list of verbs by using Verbs proerty of the process. Just like this:

ProcessStartInfo stInfo = new ProcessStartInfo(fileNameWithExtension);
foreach(string verb in stInfo.Verbs)
{

Console.WriteLine(" {0}",verb);
}


Notice that after you ran the process, changing the value of StartInfo property does not effect on the running process.

And you can use specific username and password withing UserName,Password property in StartInfo but if you set thses property the process starts in new window even if the CreateNoWindow property value is true of the WindowStyle property value is Hidden.

Getting processes on local or remote machine

The Process class in System.Diagnostics namespace, provide information about processes on current or a remote machine.

You can get list of all process on your local machine by this line of code:

Process[] process = Process.GetProcesses();

or if you want to have a list of a remote computer process list:

Process[] processList = Process.GetProcesses("machineName");

You can also use IP instead of computer name if desired.
There are also some static methods that help you to get specific process by it 's Name/Id on local or a remote computer.

Process proc = Process.GetProcessesByName("notepad");

Then you can get some information about the process. For instance in the line below I 'm getting the process filename from the MainModule property:

foreach(Process proc in Process.GetProcesses())
{

Console.WriteLine(" ProcessName : {0}, File Name: {1}",proc.MainModule.ModuleName, proc.MainModule.FileName);
}


If you want to stop a process you can use the Kill method on that process. But notice that if the process cannot be terminated you will get a Win32Exception or if the process has already exited you will get an InvalidOperationException.

It 's important to know when you are using Kill method, that you can only Kill local processes and if you try to terminate a remote process by calling Kill method, you will get a SystemException.

Saturday, May 19, 2007

Adding Removing Items from ListBox

I this simple sample code, I 've two Listboxes which in the Left Side there is a list of cars, and you can add/remove Item from/to the RightListbox.

I 'm holding all cars, and selected cars in session two keep over post backs.
If you want to enable multi select on the sample put

SelectionMode="multiple"

for the listboxes.

You can download the code here:
http://www.tabatabaei.info/csharpsamples/AddRemoveItems.zip

Uploading Multiple Files

Sometime in your web application, especially the ones which is working with files, you may need to upload more than one file in a web page. While you don't know how many files you have to upload it seems to be a good way to create a control which can upload one or more dynamically.

The first thing that I 'm going to do is to place a FileUpload control in my control and a button for upload and a link for a new file upload control. Like this:

<div>FileName: <asp:FileUpload ID="FileUpload1" runat="server" /> <asp:LinkButton ID="lnkAddMore" Text="Add More..." runat="server"OnClick="lnkAddMore_Click"></asp:LinkButton> <asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="btnUpload_Click" /><br /> <div runat="server" id="divFileUpload"> </div></div>

notice that, inside the last div I put another div which is a server html control.

Then in the link button event handler I wrote some codes like this:


protected void lnkAddMore_Click(object sender, EventArgs e)
{
FileUpload fileUpload = new FileUpload();
Literal lt = new Literal();
lt.Text = "<br/>";

divFileUpload.Controls.Add(fileUpload);
divFileUpload.Controls.Add(lt);

AddedControls.Add(fileUpload);
AddedControls.Add(lt);
}

I put the "AddedControls" property on the control which is List to keep all the added controls in the Session. The point is that we have to keep them to add in each and every post back.


protected List AddedControls
{
get
{
if (Session["AddedControls"] == null)
Session["AddedControls"] = new List();
return (List)Session["AddedControls"];
}
set
{
Session["AddedControls"] = value;
}
}

So, for adding this controls every time I create the event handler for "PreInit" event:


protected void Page_PreInit(object sender, EventArgs e)
{
foreach (Control ctrl in AddedControls)
{
divFileUpload.Controls.Add(ctrl);

}
}

In the last part, I 'm saving all the uploaded files using "Request.Files" property in Upload button event handler:


protected void btnUpload_Click(object sender, EventArgs e)
{
for (int i = 0; i < Request.Files.Count; i++)
{
HttpPostedFile file = (HttpPostedFile)Request.Files[i];
if (file.ContentLength > 0)
{
try
{
file.SaveAs(Request.PhysicalApplicationPath + "\\UploadedFiles\\" + file.FileName.Substring(file.FileName.LastIndexOf("\\") + 1));
}
catch (Exception ex)
{
Response.Write("" + ex.Message + "");
continue;
}
}
}
}

in HttpPostedFile class there is a SaveAs method which I 'm using to save my files to the server. The method need a physical path so I provide it by Request.PhysicalApplicationPath.

You can download the sample code here:
http://www.tabatabaei.info/dynamicfileupload.zip

Saturday, May 12, 2007

Ehsan 's blog

Congratulations to Ehsan, for starting his weblog "EhsanBrainDump".

As you may know "Ehsan Shalchian" is one my friend and of course one of my great teachers who is famous for his knowledge over "Software Analysis & Design Patterns" and "C#" and also too many software engineering related technologies.

I suggest you to review his posts which of course would be valuable posts.

ASP .NET References

As many of my students ask from me to give them some references for ASP.NET, I will introduce a web log post from "Bill Evjen" who has wrote some books in C# and VB .NET. http://geekswithblogs.net/evjen/archive/2004/12/10/learnaspnet.aspx He has categorized some Subjects over ASP.NET. Take a look, it worth.

Getting All Selected Items of CheckListBox

Oh, after a while again I decided to start writing on this blog.

Any way, I thing sometimes it happens that you need to show some choices to your users then ask them to select any many as they want. So as you may know the best choice is CheckListBox. So after Binding it or adding your items into it you may want to get a list of SelectedItems over the checklistbox. So you have to iterate over your items then check whether if the item is checked or not like this:


foreach (ListItem item in CheckBoxList1.Items)
{
if(item.Selected)
{
Response.Write("<h3>" + item.Text + "</h3>");
}
}

Do not forget comments.