January 2008 - Posts

I knew it's there all over the web, and people are still asking, so, let's go through it together!

Most simple Visual Studio 2005 add-ins could actually work with Visual Studio 2008. I'm not talking about huge add-ins like Resharper here, but most of the small utilities we find online. If you really want to keep using your add-in, and it doesn't provide a VS 2008 version yet, and you didn't have VS 2005 installed on the machine when you installed VS 2008 (as it tries to migrate the add-in when you install it in presence of VS 2005), there's is something very simple you can try that can work for many VS2005 add-in.

Install the VS 2005 add-in. Under your "My Documents" ("Documents" in Windows Vista), you'll see 2 folders: "Visual Studio 2005" and "Visual Studio 2008". The "Visual Studio 2005" folder will have a sub folder called "Addins". If that folder contains your add-in, and it has a file with the name of the add-in (maybe not exactly the name) and extension ".addin", then you are OK.

Just copy the add-in files (or the contents of the entire "Visual Studio 2005\Addins" folder) to the "Visual Studio 2008\Addins" folder. Note that "Visual Studio 2008\Addins" might not exist, then you just need to create the "Addins" folder under "Visual Studio 2008" folder yourself (which all is in your "My Documents" or "Documents" folder if you forgot already!).

The last step is to open the ".addin" file with any simple text editor, like Notepad. You'll see that it is a simple XML file that an be easily edited. Simply look for some tag called "<HostApplication>" and a child tag in it called "<Version>", and change the contents of that tag (You may find it more than once) from "8.0" (which maps to VS2005) to "9.0" (yes, your guess is right, that's VS2008!).

Below a screenshot of the ".addin" file for the "CopySourceAsHtml" popular add-in after applying the changes:

CopySourceAsHtml

Disclaimer: Of course I have to repeat: This should work with many VS add-ins, but it will not work with all of them.

The "C# 3.0 in a nutshell" book has some neat free extras that are worth mentioning for those who haven't already heard of (they have been released for long). Those are like must-have LINQ tools and helpers.

The homepage of LINQKit (the major part of the extras I'm going to cover here) provides great information and short code samples about the components:

  • LINQPad

    This is a snippet compiler (application to run/try small codes in separation than big VS projects, like this), that's customized for LINQ queries. You can use the SQL Server Query Analyzer -like application to try your codes on the tables in the DB, and see the resultant output and SQL query. Very useful for learning LINQ and/for for making up complex LINQ Queries

  • PredicateBuilder

    This is a dynamic query library. If you ever tried LLBLGen (one of the best .NET OR mappers), it's equivalent to PredicateExpression and PredicateFactory stuff. If not, then it's a dynamic way of creating queries. Sometimes you want to add/remove conditions to/from your query based on runtime decisions, and you can't do that with the standard query way, so, this library allows you to write code like this:

    var predicate = PredicateBuilder.False<Product>();
    foreach (string keyword in keywords)
    {
        string temp = keyword;
        predicate = predicate.Or(p => p.Description.Contains(temp));
    }

    Of course you could wrap the ".And" and ".Or" parts in an "if" statement based on any check you like, which is the real power here!

  • Improvements / Workarounds

    When you deal with LINQ much enough, you'll get many limitations (as everything else :D). For example, sometimes you cannot set conditions on related entities (like setting conditions on the "Pruchase"s of a "Customer". Also, you'll want to do more with the expressions you use, mainly combine two different expressions together, use advanced queries with related entities, doing more stuff asynchronously, etc. The LINQKit has many small extension methods you use in your normal query or your dynamic query to work around that and more.

  • LINQBridge

    If you find that you have to work on some .NET 2.0 project, it doesn't mean you lose LINQ. LINQBridge allows you to write queries like this one.

    int[] numbers = { 5, 15, 7, 12 };
    var query = numbers
      .Where (n => n > 10)
      .OrderBy (n => n)
      .Select (n => n * 10);

Check out the extras page for more code samples and the library download with demo solution and library source code.

Technorati Tags: ,,,
Note:
This is ported from my old weblog. Originally published August 28, 2006

In the past to years, and even before, I used to get tons of SPAM of different types from my FRIENDS and members of yahoo groups I'm subscribed to. Of course this used to get me annoyed, and in most cases, the sender didn't know that what s/he is sending is sort of SPAM, so, I used to send individual emails to these friends about it, and I got sick of how many messages I have to send weekly.

I thought I should send some general message to some of those, without turning myself into a SPAMMER as well! So, I started with a group whose main topic is Dr. Ahmed Khaled Tawfeeq, a great Egyptian writer who was originally known for his very special horror series. Sort of, I tend to consider some of the messages sent to that group SPAM, and I wrote about it. After finishing the message, I thought I should drop it here for general benefit.

Subject: Regarding the unrelated messages sent to this group

Hello all,

Hope you're doing great.

This is Mohamed Meligy, an Egyptian computer engineering student and web application developer, and (most importantly) a member of this great group for a quite number of months now. I'm writing this message as a big fan of the group and of Dr. Ahmed in general; a fan who also has a technical background.

This message is about some other messages group members get, which have nothing to do with the main topic of the group, or even the group itself. This group is named after Dr. Ahmed, and therefore, a new group member would expect to find in our archive some information about this great writer, his workings, news, etc..., or maybe even about his field (writing), the other writers Dr. Ahmed himself likes to read, and so; at least, some messages about the community of fans Dr. Ahmed has. Of course, as any other group it's expected from time  to time, to have some message related to the group itself. Maybe a real life meeting for some of us, a new feature supported in the groups page, someone of the group has some big event and we are sharing him/her in it, or even some message about a certain group policy to be applied, as this one is.

Unfortunately, this is not always the case in our group! Yes, thankfully, many messages are, but, we still have other non related messages. Anyone wants to write anything and spread it just puts all his/her friends emails and all the groups s/he knows and clicks "Send"; but guess what ? This is one type of SPAM (also known as Junk Mail). Organizations all over the world are fighting SPAM and helping massive email servers (like Hotmail, yahoo and gmail) block the emails of the SPAM senders. Sure you don't want our group email address to be blocked, are you?

So, some examples of SPAM are advertisement. This is the most direct one and many people help spread it. Some site says that you'll win a laptop, cash, or whatever if you send a message to at least certain number of people. Some site you subscribe says why don't you invite your friends to it, etc... I think you know what I'm talking about in here, so, let’s just stop talking about it.

The other type is false stories. Someone says that Some shape of a flower or something looks like saying "Allah", or that Bill Gates has become a Muslim and tells you to forward this to all you know. In fact, you have to think a 1000 time before you forward a message to say to you "forward me" to even ONE person. Most of those are usually SPAM; and for the example I mentioned about false news, unfortunately, many messages like these (especially the ones with Arabic or Islamic nature) were proved to be made by Turkish and Jewish people to make fun of Arab and Muslims.

Do you like to be laughed at? Do you like to be spreading some false news? The bad thing about this is that false news appears to be false soon or later, and when they are, people get VERY disappointed. It's like people needed prove that Islam or Arabic nature s a good thing. Hey, do we need false news to prove that Islam is right???!!!! And what about when all know this news was false, wouldn't that mean that Islam is not right?????? Of course NO, but some weak hearts might think so, that's why bad guys keep sending such messages, and some of us help them just because they don't know!!

The last type I'll be talking about here is religious messages. OK, how can for example Islamic messages be SPAM?? Let me tell you; it's not only that some Islamic messages tell you false stories about those who didn't forward them (sad ones, like getting ill or annoyed or lost someone they loved and so), or who forwarded them (happy ones, like having problems solved and so), but also even if the message didn't contain any of this, it could still be SPAM!

The problem with these messages is they are unexpected, and in many cases repeated (more than 10 copies sometimes, not from the same person or to the same group of course). For example, when I check my inbox, I usually have either work emails (most of these separate email address anyway) messages from technical sites (like Microsoft Developer Network), messages from my friends telling me some news related to work or some arrangements, messages from my family members abroad welling me to tell something to the other relatives in Egypt, and so. As you see, these are all important messages and some of them are URGENT. My inbox is already loaded with many new messages every few days although I have good SPAM filtering and use custom filters to put messages automatically in folders (or labels, because I'm using Gmail). Finding soo many other non very important non urgent and sometimes repeated messages is over loading on me, and sure is the same for you. These messages sometimes make me not realize the URGENT messages and provide suitable response quick enough, and this is bad. All I think then usually is:

If I didn't ask you to send me this message, and I didn't expect you to send it (or any message of the same type), and sometimes if I don't you as a sender personally in the first place, WHY for God sake are you sending me this message????

I hope you now know what I'm talking about. I hope my words are not disappointing to you, and I'm sorry for the long message, but I've been sending MANY direct responses to SPAM sent by people who are not supposed to be SPAMMERS that I got sick of it. So, I'd like to end this by giving you some advises (or call them requests) to help reduce SPAM:

  • When you're sending mail
    • If you want to spread something, look for a group that's interested in your topic and send to it. so that you can guarantee that that your message is sent to the right audience (by the way, there're many Islamic groups out there). If you don't find a group, create one, and send it's URL to your friends (But PLEASE, send it ONCE only, otherwise it's advertising SPAM)
    • Don't send the same message twice, especially when you're sending to someone you don't know that well. Only send twice if you request a confirmation on the message, and it's urgent one, and you don't get confirmation after a period of time.
    • Don't give your friends' emails (or your email username and password) to ANY site to send them invitations or so. This will most likely will be used by the site to send SPAM to them. If you really like the site, it's OK to send them about it yourself I guess. Oh yeah, try not to leave your own or your friends' email in public pages ( like forums), because there're people and software that collect emails from such places to send them SPAM afterwards.
    • When you are sending something to a number of friends who don't know each other, don't put them all in your "To" or "CC" field. This way all your friends will see all the other friends' emails. So, if some friend comes sometimes and send a message to any of the other friends s/he doesn't know, and the the friend doesn't like it, this other friend will blame YOU for it. To avoid this, put one address only in the "To" field (doesn't matter which), and put all the others in the "BCC" field. This way, each friend will only see his/her email ONLY.
    • If you get some message from someone who didn't follow the previous advice, don't use this and send mails to all the mails in the "To" and "CC" fields of the message (unless you're sending a related non-personal replay), because, if you do, most of those people (at least) will be VERY annoyed, and may block you as a SPAMMER.
  • When you are receiving mail
    • If you get some cool news, PLEASE be 100% sure it's true before you tall anyone about it. Learn to choose the right source for making sure (that's usually the most famous sites on the topic of the message).
    • Use Filters: In most email hosts like Hotmail/yahoo/gmail (and email programs too, like Outlook), there's an option to make filters on emails that automatically do a certain actions to the messages that match the filter. Use filters to put the messages with the same topic in folders (or labels if you're using Gmail), so that you can see less messages in your inbox and know what messages is about what topic without reading all the messages you get. By the way, messages with the same topic are usually sent from the same sender(s) or have the same certain keywords, or a certain prefix in the message subject.
    • If you get a messages from unknown sender, and you think it's SPAM, BLOCK the sender. Most likely s/he is a SPAMMER no more, and you'll get nothing from him/her other than SPAM messages. (yes, it's not a risk, this is a tested approach). If you get this message as a member of a group, move to the next advice.
    • Help your friends: If you get an expected message from a friend or a group member who doesn't know that what s/he's doing is SPAMMING, send him/her a short note to tell him/her about it. End this note with a polite request that if s/he is not convinced, s/he shouldn't include you in such messages anymore.
    • Don't leave your primary email in many sites unless your email host has a powerful SPAM filtering (Gmail is sort of good in this). If you receive many messages from some site, group or forum, check if you can change some option in that site to disable at least most of these mails, if not, send a short note to the site admin as a reply to any of these messages, if this all doesn't work, don't be very sorry when you mark this site email address as SPAM.
  • Thank you very much,

    Technorati Tags: ,,,
    Note:
    This is ported from my old weblog. Originally published June 22, 2006

    First, I assume here that you know themes and read about them, but are a bit afraid or unfamiliar with using them. If you don't know what are Themes and skins in ASP.NET 2.0, check their section on MSDN as well as this great article (another one).

    Do you know that...

    • Do you know that you can provide intellisense to skin files in VS2005? Simply go to Tools menu, click Options, and from the tree in the left, expand the node "Text Editor" to  click it's sub node "File Extension". In the "Extension" text box, write "skin", and select "User Control Editor" from the "Editor" drop down, click add, and then OK.
    • Do you know that ANY stylesheet existing in the folder of the current "Theme" or "StylesheetTheme" is inked on rendering? Not just the stylesheet with the same name of the Theme, and not only when you're using the theme as "StylesheetTheme" as some believe.
    • Do you know what differences exist between setting a theme using the Page Theme" property and the Page "StylesheetTheme" property?
      • If you have the same property on a control in the page and the same type of control in the skin file with different values, the value used will be the value in the page if you'te setting the theme via the "Theme" Page property, and will be the one in the skin file if you're using "StylesheetTheme"
        The bottom line is that a "Theme" is applied AFTER page controls properties are set, while a "StylesheetTheme" is applied before setting control properties in the page.
      • If you set the your theme by using the "Pages" "Theme" property in web.config, you'll NOT see the effect of the theme in design time in VS 2005. Setting "StylesheetTheme" makes the effect appears in design time.
    • Do you know that to change the theme of the page programmatically, you have to set it before the "Init" event of the page? (i.e in the "PreInit" event).

    Making real use of themes

    Have you been in the famous template graphics problem?

    • You have a template (lets say a Masterpage) used in all site pages.
    • The designer gives you the website design with some images in it of course, and one or more stylesheet file(s), which you need to reference in your template.
    • Of course, not all the site pages are in the same folder.
    • On your development box; either you're using IIS or ASP.NET development server, the site i likely to be a virtual folder, while on the production server, the site is likely to be on the root of some domain.
    • You don't know how to reference the images/stylesheet(s) in the template.
      1. You can't make them relative to the page, as simply not all the pages are in the same folder.
      2. You can't use root relative paths, as the root of the site on your machine is simpley not the root of the site on the live server.
      3. You want to reduce the number of server side images used in your side, for the performance, so, you aren't just into mking a server side control just to make ASP.NET take care of the paths.
      4. You (and your designer) hate the ugly lines like
        <img src='<%= Page.ResolveUrl("~/images/myImage.gif")%>' alt="Just a sample" />
        hint: "~" is used to refer to the root of the ASP.NET application, whether a virtual directory or a root.

    A new solution other than described in point 3,4 comes with ASP.NET themes.

    1. You can just apply a default theme to all your site (ie. by writing it in web.config)
    2. If your designer is that geek he should be, he'll be doing most of his work in a stylesheet, move that stylesheet to the folder of the theme you use.
    3. Any relative url in CSS is relative to the CSS file itself not the page using it.. As the stylesheet will be linked from a consistant place, just put the graphics folder(s)beside your CSS file(s), to be linked from there.
    4. Use a skin file with the same filename as the skin folder name, inside which, apply all server controls styles.

    Of course, as you see in point 4, this doesn't solve it completely. You'll still need to use server side controls where CSS doesn't just fit.

    An interop hint!

    No.. No unmanaged stuff here :-D. I mean by interop, your interop with your cool designer ;-).

    Let's imagine this scenario:

    1. There're many listing pages (i.e, in site admin) with many grids that should have the same design applied.
    2. Your designer gives you only a sample HTML table with a CSS class for the table, the odd rows and the even (alternate) rows, with corresponding CSS file of course.
    3. You don't want to go through the "___Style" properties of each grid to set the CSS classes. You want to set a single property (like a CSS class or something) on the entire grid. You tell your designer and he just doesn't see why he should bother!

    A solution to that repeated scenario (I've gone through and saw with MANY designers) in ASP.NET 2.0 using themes would be:

    1. Of course implementing a site wide theme, and adding the stylesheet file there.
    2. Adding a skin file with other filename than the theme folder name.
    3. Setting the "___Style" and "CssClass" properties of the controls you need (i.e: GridView).
    4. Setting the "SkinID" property on all the corresponding controls in the pages (i.e all the GridView controls that should use that design) to the filename of the new skin file (this will be our single value we need to set on the entire grid)

    Of course, the same way can be used to solve similar problems.

    Finally, I know that developers hate to see much talk without code or at least screenshots. I'm considering putting some code with this soon, but, I'm likely to forget or not have time, so, I hope this one doesn't annoy you that much as it's now

    I'm new to ASP.NET Weblogs. Thanks to Joe Stagner of course who setup my weblog account and whom I have thrown tons of questions at (Poor Joe. All day answering my messages!). I'm also an old member of GeeksWithBlogs (since January 2005) and cannot just slip away like that! So I considered cross posting, as  a permanent procedure, not temp. one.

    To do cross posting from a Community Server weblog like ASP.NET weblogs to any blog that supports MetaWeblog APIs like SubTEXT (which GeeksWithBlogs.NET uses), the steps are really easy:

    1. You login to your community server blog control panel
    2. You expand "Global Settings" from the left menu and click "Spam, Ping and Cross-Posting"
    3. You click "Setup a new blog" and enter your MetaWeblog API enabled blog

      You can see my settings in this screenshot:
      Untitled picture
    Note:
    This is ported from my old weblog. Originally published April 07, 2005

    There was a question in Microsoft Forums regarding the new modifier in C# and what's the difference between using it and using the virtual and override modifiers. I wanted to share that here as well.

    The
    new modifier is mainly used for hiding the non virtual methods. Unlike override modifier, it's used to hide all class members not only methods (i.e. variables and properties). If you create a Base class with a protected, internal or public int for example, and inherit that Base in another class called Child, placing another x in it and try to compile this, the code will compile successfully! However, if you look at the tasks window (assuming that you are using VC#) you'll see a warning that you should use the new keyword with the second declaration. A simple code should tell you what I mean here:

    using System;

    namespace ConsoleView

    {

          public class Base

          {

                ///

    The original member

                public int x;

          }

          public class Child:Base

          {     
               
    //

    This declaration will compile well, but,

                //will generate the following warning :

                //%CodeFilePAth%(%LineNumber%):

                //The keyword new is required on 'ConsoleView.Child.x'

                //because it hides inherited member 'ConsoleView.Base.x'

                public int x;
                }
    }

    Anyway, this is not the primary purpose for the modifier. The main purpose comes when you use it to hide a method instead of using override (by the way, to hide a method, you can't use both override and new. This gives you an error not just a waning).

    Using virtual and override modifiers will always be similar to using the new modifier except that when you use virtual and override you can't call the the Base class except from inside the Child class itself (meaning from the Child class methods only). To make this clearer, if you cast the child as Base and call the virtual method, you'll still get the overriden version not the vertual (original) one. This happens becasue override totally replaces the Base virtual method. It doesn't just hide it.

    Now, if you leave the original Base method with or without the virtual modifier (it doesn't matter here), and use the new modifier with the Child version of this method, you'll be hiding the original method only when Child is treated as a Child (Not casted as Base). If you cast it as Base, and call the same method, you'll get the original version of the method, not the new one.

    If you feel confused, check the following code segment:

     

    using System;

    namespace ConsoleView

    {

          //This holds only original versions of the methods

          public class Base

          {

                //This method will be overriden by Child, so, it'll never execute

                public virtual void View()

                {

                      Console.WriteLine("Viewing Base, Original virtual View");

                }

     

                //This method will be hidden only from inside Child (using 'new' modifier)

                //Note that I could make it virtual too, this wouldn't change anything

                public void ViewNew()

                {

                      Console.WriteLine("Viewing Base, Original OLD ViewNew ;)");

                }

          }

     

          //this class holds all the edited versions of methods

          public class Child:Base

          {    

                //Here I use override to permanently replace the original method

                //Whatever the reference type is,

                //    this'll always be the method executed when you call View()

                public override void View()

                {

                      Console.WriteLine("Viewing Child, override View");

                }

     

                //this hides the method only if the refernce type is Child or inherited from Child

                //a call from a reference of type Base will execute the OLD method, not thiis one

                public virtual new void ViewNew()

                {

                      Console.WriteLine("Viewing Child, new View");

                }

          }

     

          ///

    Used to hold the 'Main' method only!

          /// to show up the result of using each in the Console

          class Implementor

          {

                ///

    The main entry point for the application.

                /// Used to show up what's the expected result.

                [STAThread]

                static void Main(string[] args)

                {

                      //This part is very typical

                      //Creating a Child reference, and it referes to (its value is) a child

                      Child myChild=new Child();

                      //Indicating reference and value types in the output

                      Console.WriteLine

                            ("The reference now is a Child that refers to a child. Typical, ha?!");

                      //Will show up the overriden version

                      //as it has been totally overriden using the override modifier

                      myChild.View();

                      //Shows up the new version,

                      //as the new modifier hid the original version

                      myChild.ViewNew();

     

                      //The difference comes here

                      //The reference is a Base, but it refers to (its value is) a Child

                      Base myBase=(Base)new Child();

                      //Indicating the previous change in the output

                      Console.WriteLine

                            ("\n\nThe reference now is a Base, yet it still refers to a child");

                      //Will show the overriden version,

                      //even though the reference is of type Base,

                      //it's been totally overriden, not just hdden

                      myBase.View();

                      //Will show the original version NOT the new one

                      //as the new hides the method in Child only

                      //it doesn't override it totally

                      myBase.ViewNew();

     

                      //Just to halt the screen so that I can read the output

                      Console.Read();

                }

          }

    }

    This code should be explainning itself on its own. I just show that when I call the virtual method 'View()' using a Child reference or Base refernce, I always get the overriden version, on the other hand, when I call the 'ViewNew()' method using a Base reference, I get the original version. I get the “new” version only when I use a Child reference (or reference of any type that is inherited from Child itself).

    This should be the output of that program:
    the C# new Keyword result of code

    A good remark is that a method can be new and virtual at the same time, just in case you wanted to allow others to override your new method, especially if the old method is not a virtual one ;)

    If you are seeking the official word from MSDN, Check MSDN LibraryDevelopment Tools and LanguagesVisual Studio .NETVisual Basic and Visual C#ReferenceVisual C# LanguageC# Programmer's ReferenceC# KeywordsOperator Keywords > new.

    Finally, just tell me if this is too much, causes you confusion, or just never helped you by any means!

     

    Technorati Tags: ,,
    Note:
    This is ported from my old weblog. Originally published December 19, 2005

    This is a well commented example for a GridView with implementation of RowDataBound and DataBound events. I also demonstrate in it some of the important properties of GridView, like the slight diffrences when dealing with Grid Paging, Rows, Cells, and Columns. I prefered to heavily comment the code than to write separate paragraphs describing it as I do believe that the code is what gets the idea in a direct way.

    The example is a simple page that uses SqlDataSource to connect to a SQL Server 2005 Express database and show the results on a GridView with paging capapility. Many parts of the code don't show the best practices for their situation and those are only included for demonstration purpose as they are not the main focus of the example.

    I'll start with the code behind of the page as it's the most important part:

    /******************************************************************
     * The sample is provided AS IS without any warranty
     * All rights reserved (C) 2005, Mohamed A. Meligy
     * http://www.GeeksWithBlogs.NET/Mohamed
     * All rights reserved (C) 2005, Mohamed A. Meligy
     * http://weblogs.asp.net/meligy
     * Distribution of this code without this legal note is prohibited.
     ******************************************************************/
     
    //Default "using" set of a new System.Web.UI.Page Visual Studio 2005 template:
    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
     
    /// <summary>
    /// To test the GridView behavior in action,
    ///     you need to have SQL Server Express installed (comes by default with VS2005),
    ///     and Northwind database attached to it
    ///     (attaches by default when you select "Quickstart Tutorials"
    ///     from the .NET Framework 2.0 SDK Programs menu, and choose to install them).
    /// Alternatively, change the ConnectionString property of the SqlDataSource
    ///     to point to another installed instance
    ///     of SqlServer 2000 or SqlServer 2005 that has Northwind database attached.
    /// </summary>
    public partial class GridViewSampler1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Limiting redundancy of useless execution.
     
            //You do no need to check IsCallback if you
            //  don't have controls with Callback Enabled.
            if (!IsPostBack & !IsCallback)
            {
                //This makes performing paging and sorting uses AJAX.
                GridView1.EnableSortingAndPagingCallbacks = true;
     
     
                //Small number so that I can see many oages out of
                //  9 rows only (Yhe total Rows Count of Northwind's Employees DataTable).
                //Also selected it in a way that last Page Rows Count will be
                //  different than other pages.
                GridView1.PageSize = 2;
     
     
                if (!IsPostBack)   //Just to prove the AJAX thing.
                {
                    PostBackStatus.Text = "Not PostBack";
                }
                else   //Never happens, as I don't require a PostBack.
                {
                    PostBackStatus.Text = "Page Is PostBack";
                }
            }
        }
     
     
        /// <summary>
        /// Executes when the databinding is complete
        /// </summary>
        protected void GridView1_DataBound(object sender, EventArgs e)
        {
     
            //I'll use it to show which set of Rows I'm showing in the page.
            GridView1.ShowFooter = true;
            //Similar to: GridView1.FooterRow.Visible = true
     
     
            //Stretching the first cell to fill the whole FooterRow:
     
            //Removing all non needed cells,
            //  from the end to start
            //  (so that the Cells collection is not recreated with every Removal).
            for (int cellNum = GridView1.Columns.Count - 1; cellNum > 0; cellNum--)
            {
                GridView1.FooterRow.Cells.RemoveAt(cellNum);
            }
     
            GridView1.FooterRow.Cells[0].ColumnSpan = GridView1.Columns.Count;
            GridView1.FooterRow.Cells[0].HorizontalAlign = HorizontalAlign.Center;
     
     
            int startIndex = GridView1.PageIndex != GridView1.PageCount - 1 ?
     
            //Not in last page.
            GridView1.PageSize * GridView1.PageIndex
     
            //GridView1 Rows Count is Count of the Rows of the current page, so,
                //  unless Paging is Disabled, this is not total Rows Count.
                //gridViewTotalCount is declared and assigned just after this method.
            : gridViewTotalCount - GridView1.PageSize + GridView1.Rows.Count;
     
     
            GridView1.FooterRow.Cells[0].Text =
                string.Format
                    ("Showing Employees {0} to {1} of {2}",
                    startIndex + 1,
                    startIndex + GridView1.Rows.Count, gridViewTotalCount);
        }
     
        TableCell myCell = null;
        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            //I'll add that to every Row bound in the GridView.
            myCell = new TableCell();
            //Note that for the header, footer, and separator rows, DataItemIndex is -1
            myCell.Text = e.Row.DataItemIndex.ToString();
     
     
            //Note that when you add the cell,
            //  this does NOT increase the GridView Columns Count.
            e.Row.Cells.Add(myCell);
     
     
            //The past lines will affect also HeaderRow, FooterRow, and even Pager,
            // you'll see when you run that this is not a desired behavior.
     
     
            //You can limit your code on condition. This is the recommended way.
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                //Do your UI logic now for data binding,
                //  much similar to DataGrid ItemDataBound.
     
     
                //Example: changing color of text
                //  for normal and alternative rows ONLY by code.
                if (e.Row.RowIndex % 2 == 0)
                {
                    e.Row.Style["color"] = "#0000ff";
                }
                else
                {
                    e.Row.Style["color"] = "#00bb00";
                }
     
                //This is the EmployeeID Cell
                e.Row.Cells[0].Text =
                    "I'm alternative employee with code: " + e.Row.Cells[0].Text;
     
     
                //Another sample change making use of the DataItem:
     
                // This is specific to our case where the GridView is bound to
                //  first DataTable in the DataSet returnd by the EmployeesSqlSource.
                // This is when SqlDataSource DataSourceMode = DataSet (Default)
                DataRowView rowView = (DataRowView)e.Row.DataItem;
     
                e.Row.Cells[GridView1.Columns.Count - 1].Text =
                    int.Parse(rowView["Extension"] as string).ToString("###-##");
            }
        }
     
        int gridViewTotalCount;
     
        protected void EmployeesSqlSource_Selected
            (object sender, SqlDataSourceStatusEventArgs e)
        {
            //GridView has no way of telling total Rows Count when paging is enabled.
            gridViewTotalCount = e.AffectedRows;
        }
    }

     

    Now to the page XHTML source:

    <%@ Page Language="C#" AutoEventWireup="true" 
        CodeBehind="GridViewSampler1.aspx.cs" 
        Inherits="GridViewSampler1"
        %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     
    <html xmlns="http://www.w3.org/1999/xhtml">
     
    <head id="PageHeader" runat="server">
        <title>GridView Sample</title>
    </head>
    <body>
     
        <form id="form1" runat="server">
            <div>
            Postback Status:
                <asp:Label ID="PostBackStatus" runat="server"></asp:Label>
     
                <asp:GridView ID="GridView1" runat="server" 
                    AutoGenerateColumns="False" AllowPaging="True"
                    DataSourceID="EmployeesSqlSource" DataKeyNames="EmployeeID"
                    OnDataBound="GridView1_DataBound"
                    OnRowDataBound="GridView1_RowDataBound">
                    <Columns>
                        <asp:BoundField DataField="EmployeeID"
                            HeaderText="EmployeeID" InsertVisible="False"
                            ReadOnly="True" SortExpression="EmployeeID" />
                        <asp:BoundField DataField="LastName" 
                            HeaderText="LastName" SortExpression="LastName" />
                        <asp:BoundField DataField="FirstName" 
                            HeaderText="FirstName" SortExpression="FirstName" />
                        <asp:BoundField DataField="Title" 
                            HeaderText="Title" SortExpression="Title" />
                        <asp:BoundField DataField="BirthDate" 
                            HeaderText="BirthDate" SortExpression="BirthDate" />
                        <asp:BoundField DataField="PostalCode" 
                            HeaderText="PostalCode" SortExpression="PostalCode" />
                        <asp:BoundField DataField="Extension" 
                            HeaderText="Extension" SortExpression="Extension" />
                    </Columns>
     
                    <EmptyDataTemplate>
                        <div style="text-align: center">
                            No Data Available.
                        </div>
                    </EmptyDataTemplate>
     
                </asp:GridView>
                <asp:SqlDataSource ID="EmployeesSqlSource" runat="server"
                    ConnectionString=
    "Data Source=MELIGY\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"
                    ProviderName="System.Data.SqlClient"
                    SelectCommand=
    "SELECT [EmployeeID], [LastName], [FirstName], [Title], [BirthDate], [PostalCode], [Extension] FROM [Employees]"
                    OnSelected="EmployeesSqlSource_Selected"></asp:SqlDataSource>
     
            </div>
        </form>
    </body>
    </html>

     

    Samples of the output of the code:




    Hope that you like it.

     

    More Posts