Wednesday, June 25, 2008

GridView ObjectDataSource Paging

Took me a lot of time to figure it out...

First, paging doesn't seem to work when ObjectDataSource Select function returns SqlDataReader so it returns DataView now.

The code looks like this:

   1: [DataObjectMethod(DataObjectMethodType.Select)]
   2:     public static DataView GetRows(int statusid, int experienceid, string submitter, string idsid, string SortExpression)
   3:     {
   4:  
   5:         StringBuilder strSql = MainSelectSql(idsid, statusid, experienceid, submitter, SortExpression);
   6:  
   7:         SqlConnection connection = Connection.GetConnection();
   8:         SqlCommand command = new SqlCommand(strSql.ToString(), connection);
   9:         command.CommandType = CommandType.Text;
  10:         SqlDataAdapter adapter = new SqlDataAdapter(command);
  11:  
  12:         //connection.Open();
  13:         DataTable dt = new DataTable();
  14:         adapter.Fill(dt);
  15:         connection.Close();
  16:         int totalRecords = dt.Rows.Count;
  17:  
  18:         DataView dw = new DataView(dt);
  19:  
  20:         return dw;
  21:     }

 

The GridView has to have its "AllowPaging" set to true and PageIndexChanging method looks like this:

   1: protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
   2: {
   3:     GridView gv = (GridView)sender;
   4:     gv.PageIndex = e.NewPageIndex;
   5:     gv.DataBind();
   6: }

 

Also can change the page size in properties...

Saturday, June 21, 2008

SQL Server 2005- OVER() partition

This will be useful for GridView pagination:

An aggregate functions can be added to any SELECT (even without a GROUP BY clause) by specifying an OVER() partition for each function.

This means that this code:

   1: select 
   2:     o.customerID, o.productID, o.orderDate, o.orderAmount, t.Total
   3: from 
   4:     Orders o
   5: inner join 
   6:    (
   7:     select customerID, sum(orderAmount) as Total from Orders group by customerID
   8:    ) 
   9:   t on t.customerID = o.customerID
can be replaced with:
   1: select customerID,  productID, orderDate, orderAmount, 
   2:       sum(orderAmount) OVER (Partition by CustomerID) as Total
   3: from Orders

Source

Monday, June 9, 2008

jQuery Selectors - How to Get Anything You Want

Great articles from Learning  jQuery blog:

How to Get Anything You Want - part 1

How to Get Anything You Want - part 2

Firefox popup blocker blocks ctrl-V from Google Reader

Found the solution on Google Groups (Google Reader Help):

1. In a Firefox window, enter "about:config" in the address bar.
2. In the "Filter" field, type "popup_maximum".
3. One preference, called "popup_maximum" appears; double-click the
"value" number.
4. Enter a new, appropriately large value. I used 2000, just to be on
the safe side.

Sunday, June 1, 2008

SQL - substring and charindex

 

   1: SELECT
   2:     substring(IdeaText,1,
   3:         charindex('//', IdeaText)
   4:     ) as part1
   5: FROM tblIdeas

 

substring

charindex

Saturday, May 31, 2008

CSS Div overlay

image

Source

Using jQuery to directly call ASP.NET AJAX page methods

 

   1: public partial class _Default : Page 
   2: {
   3:   [WebMethod]
   4:   public static string GetDate()
   5:   {
   6:     return DateTime.Now.ToString();
   7:   }
   8: }
   1: <html>
   2: <head>
   3:   <title>Calling a page method with jQuery</title>
   4:   <script type="text/javascript" src="jquery-1.2.6.min.js"></script>
   1:  
   2:   <script type="text/javascript" src="Default.js">
</script>
   5: </head>
   6: <body>
   7:   <div id="Result">Click here for the time.</div>
   8: </body>
   9: </html>
   1: $(document).ready(function() {
   2:   // Add the page method call as an onclick handler for the div.
   3:   $("#Result").click(function() {
   4:     $.ajax({
   5:       type: "POST",
   6:       url: "Default.aspx/GetDate",
   7:       beforeSend: function(xhr) {
   8:         xhr.setRequestHeader("Content-type", 
   9:                              "application/json; charset=utf-8");
  10:       },
  11:       dataType: "json",
  12:       success: function(msg) {
  13:         // Replace the div's content with the page method's return.
  14:         $("#Result").text(msg.d);
  15:       }
  16:     });
  17:   });
  18: });

 

Source

Using an XML file for your ASP.NET settings

 

Step 1: Setup

To begin, I would create an XML file in the App_Data directory of your application. For this example, I will call the file Settings.xml. If you're using Visual Studio just right click the App_Data folder and Add a new item. The file will be pre-filled with the standard xml encoding:

<?xml version="1.0" encoding="utf-8" ?>

You should then add a root element to the XML file. I chose the root element to be <settings></settings>. Within those tags, all of your settings will be listed out as child elements. So far the file looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<settings>
</settings>

Save the file to the App_Data folder.

Step 2: Create the Settings.cs class

Next, create a Settings class in your App_Code folder (or name it whatever you like). This class will be responsible for retrieving and updating the data in the Settings.xml file. Set the class to static so that it is only loaded once for the application.

Step 3: Define the setting elements and properties

You should now begin entering the settings you'll be using for the application. In the Settings.xml file, create an element for each of the settings you will need for your program and pre-populate them with defaults if you like.

Tip: If your setting contains any markup or unsafe characters, surround the settings in the <![CDATA[ your_setting_value_here ]]> tag to avoid xml errors.

I've added some example setting elements to my Settings.xml file below:

<?xml version="1.0" encoding="utf-8"?>
<settings>
    <MaxImageUploadSizeKB>1000</MaxImageUploadSizeKB>
    <ThumbnailWidth>100</ThumbnailWidth>
    <ThumbnailHeight>90</ThumbnailHeight>
    <UploadedImageDirectory>~/images/postImages/</UploadedImageDirectory>
    <SessionExpiresMinutes>20</SessionExpiresMinutes>
</settings>

Next, for each of the settings you added to the Settings.xml file, create a property for it in the Settings.cs class. I'm assuming >= .NET 2.0 for the code here.

   1: public static class Settings
   2: {
   3:      /// <summary>
   4:     /// The maximum file size in KB for uploaded images. [Default: 1000KB]
   5:     /// </summary>
   6:     public static int MaxImageUploadSizeKB { get; set; }
   7:  
   8:     /// <summary>
   9:     /// The whole number integer width of the image thumbnails [Default:100]
  10:     /// </summary>
  11:     public static int ThumbnailWidth { get; set; }
  12:  
  13:     /// <summary>
  14:     /// The whole number integer height of the image thumbnails [Default:90]
  15:     /// </summary>
  16:     public static int ThumbnailHeight { get; set; }
  17:  
  18:     /// <summary>
  19:     /// The directory to upload and read post images from/to [Default: ~/images/postImages/]
  20:     /// </summary>
  21:     public static string PostImageDirectory { get; set; }
  22:  
  23:     /// <summary>
  24:     /// The number of minutes before a checkout session expires. [Default: 20]
  25:     /// </summary>
  26:     public static int SessionExpiresMinutes { get; set; }
  27: }

Step 4: Read the XML file into the properties

I'm sure I will catch some heat for using a DataSet to read the XML file as it seems to go against the whole point of using an XML file in the first place, but I like the simplicity and readability of the code it produces...Plus it's dead easy. The following function will assign the properties in the Settings class to the values in the XML file:

   1: /// <summary>
   2:     /// Load the settings from Settings.xml
   3:     /// </summary>
   4:     public static void LoadSettings()
   5:     {
   6:         DataSet ds = new DataSet();
   7:         ds.ReadXml(HttpContext.Current.Server.MapPath("~/App_Data/Settings.xml"));
   8:         if (ds != null && ds.Tables[0].Rows.Count > 0)
   9:         {
  10:             DataRow dr = ds.Tables[0].Rows[0];
  11:             MaxImageUploadSizeKB = Int32.Parse(dr["MaxImageUploadSizeKB"].ToString() ?? "1000");
  12:             ThumbnailWidth = Int32.Parse(dr["ThumbnailWidth"].ToString() ?? "100");
  13:             ThumbnailHeight = Int32.Parse(dr["ThumbnailHeight"].ToString() ?? "90");
  14:             PostImageDirectory = dr["UploadedImageDirectory"].ToString() ?? "~/images/postImages/";
  15:             SessionExpiresMinutes = Int32.Parse(dr["SessionExpiresMinutes"].ToString() ?? "20");
  16:         }
  17:     }

Note that the ?? operator will use the value following the ?? if the expression before it is null. This allows you to hard code defaults if you desire instead of having to do so in the XML file.

Now that you have the properties filled with data from the XML file, you can use them in your application just by referencing Settings.ThumbnailWidth for example.

Source

Detect the Status of a Windows Service

When developing software that relies upon the availability of Windows services, it is important to be able to determine a service's status.  This article explains how to check if a service is running, either on a local computer or on a remote server.

Source

Windows: Remove the "Use web to find program to open Unknown File Type"

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Policies \ Explorer

Now in the right pane of the window create a 32-bit DWORD value:

  • Name: NoInternetOpenWith
  • Value: 1

Wednesday, May 14, 2008

WinForms - Using Mutex to force only one instance of Form

   1: static class Program
   2:  {
   3:      ///<summary>
   4:      /// The main entry point for the application.
   5:      ///</summary>
   6:      [STAThread]
   7:      static void Main()
   8:      {
   9:          bool instanceCountOne = false;
  10:  
  11:          using (Mutex mtex = new Mutex(true, "MyRunningApp", out instanceCountOne))
  12:          {
  13:              if (instanceCountOne)
  14:              {
  15:                  Application.EnableVisualStyles();
  16:                  Application.SetCompatibleTextRenderingDefault(false);
  17:                  Application.Run(new Form1());
  18:                  mtex.ReleaseMutex();
  19:              }
  20:              else
  21:              {
  22:                  MessageBox.Show("An application instance is already running");
  23:              }
  24:          }
  25:      }
  26:  }

Add custom row to GridView

   1: public partial class _Default : System.Web.UI.Page
   2: {
   3:     static int pgSize;
   4:  
   5:     protected void Page_Load(object sender, EventArgs e)
   6:     {
   7:         if(!Page.IsPostBack)
   8:               pgSize = 0;
   9:     }
  10:  
  11:     protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
  12:     {
  13:         if (e.Row.RowType == DataControlRowType.DataRow)
  14:         {
  15:             TableCell tCell = new TableCell();
  16:             // create image
  17:             Image img = new Image();
  18:             img.ImageUrl = "subheader.jpg";
  19:             // add the image to the cell
  20:             tCell.Controls.Add(img);
  21:            
  22:             GridView gView = (GridView)sender;
  23:             // set the colspan to occupy the other cells in the row
  24:             int colSpan = gView.Columns.Count;
  25:             tCell.Attributes["ColSpan"] = colSpan.ToString();
  26:  
  27:             GridViewRow gRow = new GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal);
  28:             // add the cells to the gridviewrow
  29:             gRow.Cells.Add(tCell);
  30:  
  31:             Table tbl = (Table)e.Row.Parent;
  32:  
  33:             // set the pagesize initially to the pagecount/2
  34:             // in our case it is 10/2 = 5. So the first image will
  35:             // displayed after the 5th row.
  36:             if(pgSize == 0)
  37:                 pgSize = GridView1.PageCount / 2;
  38:  
  39:             // This step is performed so that we can display the image only after every
  40:             // 5, 15, 25 ,35 rows and so on ...
  41:             // The logic is not perfect but will give you the idea
  42:             if (Convert.ToDouble(e.Row.DataItemIndex + 1) / Convert.ToDouble(pgSize) == 1.0)
  43:             {
  44:                 tbl.Controls.AddAt(gView.Controls[0].Controls.Count, gRow);
  45:                 // add 10 to the pgsize so that the image can be displayed
  46:                 // at rows 5, 15, 25 and so on..
  47:                 pgSize = pgSize + 10;
  48:             }
  49:         }
  50:     }
  51: }