May 2 2006

WebSetp Project & Visual Studio 2005 Web Deployment Projects

Category: ASP.NET 2.0 - GeneralBil@l @ 08:52

As you all know, Visual Studio 2005 Web Deployment Projects has be officially launched. Out of the cool things I like when working with WDP is the ability to include the WDP in a web setpup project.

Assuming you have created your webs application, class library(ies), added Web Deployment Project.

  • Add a new Web Setup Project:
  • Right-click, View --> File System
  • You will notice Web Application folder, right click, add, project output
  • Choose the Web Deployment Project.
  • Build Solution

You will notice the ".msi" file created that, once deployed, it will be deploying the Web Deployment Project now instead of deploying the whole web aplication.

HTH,

Reagrds

Tags:

Apr 29 2006

Define an Event Handler for a HyperLink Server Control

Category: ASP.NET 1.x | ASP.NET 2.0 - GeneralBil@l @ 09:37

Hello, a common question on the ASP.NET Forum is:

How to define an Event Handler for a HyperLink?

The solution as follows:

protected System.Web.UI.WebControls.HyperLink HyperLink1;
    
private void Page_Load(object sender, System.EventArgs e)
{
    HyperLink1.Attributes.Add("onClick",
Page.GetPostBackEventReference(this.HyperLink1,"HyperLinkPostBack$"+this.HyperLink1.ID)); if ( (IsPostBack) && (Request.Form["__EVENTTARGET"] != null) && (Request.Form["__EVENTARGUMENT"].ToString().StartsWith("HyperLinkPostBack")) ) { string[] args = Request.Form["__EVENTARGUMENT"].ToString().Split('$'); if ( (string.Compare(args[0], "HyperLinkPostBack", false, System.Globalization.CultureInfo.InvariantCulture) == 0)
&& (args.Length > 1) ) { HyperLinkHandler(args[1].ToString()); } } } public void HyperLinkHandler(string ID) { Response.Write("You clicked HyperLink with ID : "+ ID); }

                
 

                
 
 Or You could use this way, using IPostBackEventHandler:

                
private void Page_Load(object sender, System.EventArgs e)
{
    HyperLink1.Attributes.Add("onClick", Page.GetPostBackEventReference(this, "HyperLinkPostBack" + "$" + this.HyperLink1.ID));
}

public void RaisePostBackEvent(string eventArgument)
{
    if (!string.IsNullOrEmpty(eventArgument))
        {
            string[] args = eventArgument.Split('$');
                if ((string.Compare(args[0], "HyperLinkPostBack", false, System.Globalization.CultureInfo.InvariantCulture) == 0) 
&& (args.Length > 1)) { HyperLinkHandler(args[1].ToString()); } } } public void HyperLinkHandler(string ID) { Response.Write("You clicked HyperLink with ID : " + ID); }

                
 

Hope that helps,

Regards

Tags: ,

Apr 28 2006

Modal Dialog Window Caching Problem

Category: ASP.NET 1.x | ASP.NET 2.0 - GeneralBil@l @ 09:35

Hello:

Suppose you open a Modal Dialog window inside your ASP.NET page. In that dialog window, you have a GridView, DataGrid, or whatever control. Do some changes on that control, you will see that the data has changed right?

Ok, then close the dialog window, then open it again from the ASP.NET Page, you will see the old data and not the data you changed last time, right?

Ok, this is because the data has been cached by the Modal Dialog. It seems that this is how Modal Dialog Windows are built to cache.

To overcome this, you would need to add the following in the top of the ASP.NET page that is being opened with the Modal Dialog:

<%@ OutputCache Location="None" VaryByParam="None" %>

Hope that helps,

Regards

Tags: ,

Apr 25 2006

Define Custom Events in UserControls

Category: ASP.NET 1.x | ASP.NET 2.0 - GeneralBil@l @ 17:55

A very common question on the ASP.NET forums is:

How to define an event in a UserControl, and process this event in the Page holding this UserControl?

The answer is simple, follow this post, and you will be able to define your own events very easily.

We have the following UserControl file together with the Code Behind as follows:

<%@ Control Language="c#" AutoEventWireup="false" Codebehind="EventUserControl.ascx.cs" Inherits="UserControls.EventUserControl" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<P>Choose a Country:&nbsp;&nbsp;
 <asp:DropDownList id="ddlCountry" runat="server">
  <asp:ListItem Value="Australia">Australia</asp:ListItem>
  <asp:ListItem Value="Canada">Canada</asp:ListItem>
  <asp:ListItem Value="Kuwait">Kuwait</asp:ListItem>
  <asp:ListItem Value="Lebanon">Lebanon</asp:ListItem>
  <asp:ListItem Value="Saudi Arabia">Saudi Arabia</asp:ListItem>
  <asp:ListItem Value="USA">USA</asp:ListItem>
 </asp:DropDownList></P>
<P>
 <asp:Button id="btnSubmit" runat="server" Text="Select"></asp:Button></P>

The code behind has been enriched with many comments to make your life easy while reading the code:

namespace UserControls
{
 #region Imports
 using System;
 using System.Data;
 using System.Drawing;
 using System.Web;
 using System.Web.UI.WebControls;
 using System.Web.UI.HtmlControls;
 #endregion

 #region Class Declaration
 public class EventUserControl : System.Web.UI.UserControl
 {
  #region Controls
  protected System.Web.UI.WebControls.DropDownList ddlCountry;
  protected System.Web.UI.WebControls.Button btnSubmit;
  #endregion
 
  #region Delegate Declaration
  // Step 2
  // Define the handler that will handle the event fired by the Button
  // It takes two arguments, the sender and a parameter of type ButtonEventArgs.
  // The ButtonEventArgs will hold the country that was selected
  // So the event handler in the ASPX page, should have the same signature
  // as that of the handler, of the event fired by the UserControl
  public delegate void ButtonClickedHandler (object Sender, ButtonEventArgs e);
  #endregion

  #region Event Definition
  // Step 3
  // Define an instance of the event handler,
  // this instance shall be filled with the event handler
  // that will be defined in the ASPX page
  public event ButtonClickedHandler ButtonClicked;
  #endregion

  #region OnEvent Event
  // Step 4
  // You always need the "On" method that will check if
  // the above event has been registered with an event handler or not
  // if it has been registered, then it will fire that event in the ASPX page
  // the page that is holding the UserControl
  public virtual void OnButtonClicked(ButtonEventArgs e)
  {
   if (ButtonClicked != null)
   {
    ButtonClicked(this,e);
   }
  }
  #endregion

  #region Control Events
  private void Page_Load(object sender, System.EventArgs e)
  {
   
  }
  private void btnSubmit_Click(object sender, System.EventArgs e)
  {
   string ddlSelectedValue = this.ddlCountry.SelectedItem.Text;

   // Step 5
   // Get a new instance of ButtonClickedArgs, fill it with the
   // Country that has been selected
   ButtonEventArgs objBCA = new ButtonEventArgs();
   objBCA.CountrySelected = ddlSelectedValue;

   // Call the method that will fire the event in ASPX page
   OnButtonClicked(objBCA);

  }
  #endregion

  #region Web Form Designer generated code
  override protected void OnInit(EventArgs e)
  {
   InitializeComponent();
   base.OnInit(e);
  }

  private void InitializeComponent()
  {
   this.btnSubmit.Click += new System.EventHandler(this.btnSubmit_Click);
   this.Load += new System.EventHandler(this.Page_Load);
  }
  #endregion
 }
 #endregion

 #region ButtonEventArgs Definition
 // Step 1
 // An object can extend the EventArgs object
 // and adds its own fields to it
 // to be able lto gather more data
 // about the event fired
 public class ButtonEventArgs : EventArgs
 {
  #region Private Fields
  private string m_CountrySelected;
  #endregion

  #region Public Properties
  public string CountrySelected
  {
   get {return this.m_CountrySelected;}
   set {this.m_CountrySelected = value;}
  }
  #endregion

  #region Constructors
  public ButtonEventArgs()
  {}

  public ButtonEventArgs(string p_CountrySelected)
  {
   this.m_CountrySelected = p_CountrySelected;
  }
  #endregion
 }
 #endregion

}

Then, the ASPX page that will hold the UserControl is defined below, through both the Code-Behind and ASPX page:

<%@ Page language="c#" Codebehind="TestEventUserControl.aspx.cs" AutoEventWireup="false" Inherits="UserControls.TestEventUserControl" %>
<%@ Register TagPrefix="uc1" TagName="EventUserControl" Src="EventUserControl.ascx" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
 <HEAD>
 </HEAD>
 <body MS_POSITIONING="GridLayout">
  <form id="Form1" method="post" runat="server">
   <uc1:EventUserControl id="EventUserControl1" runat="server"></uc1:EventUserControl>
  </form>
 </body>
</HTML>

The code behind is as follows:

#region Imports
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
#endregion

namespace UserControls
{
 public class TestEventUserControl : System.Web.UI.Page
 {
  #region Define UserControl
  // Step 1
  // Define an instance of the UserControl
  // to be able to add an event handler
  protected EventUserControl EventUserControl1;
  #endregion

  private void Page_Load(object sender, System.EventArgs e)
  {
   
  }
  
  // Step 3
  // The event handler, whose signature is the same as the ButtonClickEventHandler
  // that will be used to handle the event fired by the UserControl
  private void EventUserControl_Fired(object Sender, ButtonEventArgs e)
  {
   Response.Write("You have choosen: " + e.CountrySelected);
  }

  #region Web Form Designer generated code
  override protected void OnInit(EventArgs e)
  {
   InitializeComponent();
   base.OnInit(e);
  }
  
  private void InitializeComponent()
  {   
   this.Load += new System.EventHandler(this.Page_Load);

   // Step 2
   // Registering the ButtonClick event with the event handler on the ASPX page
   this.EventUserControl1.ButtonClicked += new UserControls.EventUserControl.ButtonClickedHandler(EventUserControl_Fired);
  }
  #endregion
 }
}

Now, you can create a new Web Application, make sure to name the Application UserControls, create a user control called EventUserControl.ascx and a page called TestEventUserControl.aspx. Those names are just named so that you can run the above code without any changes, however, feel free to change them to whatever names you want.

Hope I was able to make it easy on you, on how to define events inside UserControl and handle them in the ASPX page that is holding the UserControl.

HTH,

Regards

 

Tags: ,

Apr 23 2006

Traverse a TreeView in ASP.NET 2.0

Category: ASP.NET 2.0 - GeneralBil@l @ 13:54

I'm working those days on an application, which relies a lot on TreeView Control in ASP.NET 2.0. However, it is not just working with it out of the box, I am forced to go down and program with the control.

However, I was trying to traverse a Tree and thought of sharing with you this piece of code:

    private void TraverseTreeView(TreeNodeCollection p_NodeCollection, int p_Level)
    {
        foreach (TreeNode _TreeNode in p_NodeCollection)
        {
            for (int i = 0; i < p_Level; i++)
            {
                Response.Write("&nbsp;&nbsp;&nbsp;");
            }

            if (_TreeNode.ChildNodes.Count > 0)
            {
                Response.Write("<b>" + _TreeNode.Text + "</b>" + "<br>");
                TraverseTreeView(_TreeNode.ChildNodes, p_Level + 1);
            }
            else
            {
                Response.Write(_TreeNode.Text + "<br>");
            }
        }
    }

You would call this method as:

TraverseTreeView(this.TreeView1.Nodes, 0);

 

Hope this helps you working with your TreeView.

Regards

Tags:

Apr 22 2006

Visual Studio 2005 Express Free For Ever

Category: ASP.NET 2.0 - GeneralBil@l @ 10:05

I read a great post from some time, that Microsoft has decided to make the Visual Studio 2005 Express Editions free for ever!!

Read more here:

Visual Studio Express Editions are Free Forever

Regards

 

Tags:

Apr 18 2006

ASP.NET 2.0 Training Center

Category: ASP.NET 2.0 - GeneralBil@l @ 13:25

I wanted to share with you a great website I passed by today:

ASP.NET 2.0 Training Center

Has lots of great resources through articles, webcasts, and others.

Make sure to visit that site.

Regards

Tags:

Apr 18 2006

Paging With ObjectDataSource in One Trip

Category: ASP.NET 2.0 - GeneralBil@l @ 11:55

This post assumes you have the previous post on the DataObjectTypeName and ObjectDataSource .

Usually, when we want to allow paging when we are using ObjectDataSource, we should enable paging in both the Data-Bound Control (GridView an example) and the ObjectDataSource.

  • GridView: AllowPaging and off course you need to set PageSize.
  • ObjectDataSource: EnablePaging, also you need to set the:
    • MaximumRowsParameterName="maxRows"
    • StartRowIndexParameterName="startRowIndex"
    • SelectCountMethod="RecordCount"

The method specified in the SelectMethod should now have 2 parameters:

  • int maxRows
  • int startRowIndex

The key point I wanted to show here is the following:

When you want to allow paging, you should add a method called SelectCountMethod, this method is used by the ObjectDataSource to know how many pages there will be.

An old conception for me has been that, we are doing two database round-trips. One to get the data and one to get the Record Count.

This is not true anymore!!! Why?

Let me explain, if the methods in the data mapper class are instance methods that is, not defined with static methods, then ODS will create an instance of the object specified in the TypeName, and access those methods, then disposes that instance.

However, if we had enabled paging, and both the SelectMethod and SelectCountMethod are both instance methods, then, the same instance will be used to access those two methods. So now, inside your Select method, you can get the count of the total records, and store it in a private instance, and then have a SelectCountMethod return that instance. This way, in one shot, you got both values, and since the "same instance" is created by the ODS, means you can for sure make use of the value of the record count, check this sample:

   [DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
    public List<Employee> Get()
    {
        // your logic to retrieve all records

        // Get the Count record
        _CountRecords = (int)dr["Count"];

        return new List<Employee>();
    }

    public int RecordCount()
    {
        return _CountRecords;
    }

Hope this helps you,

Regards

Tags:

Apr 18 2006

DataObjectTypeName and ObjectDataSource

Category: ASP.NET 2.0 - GeneralBil@l @ 10:32

For most of you using the ObjectDataSource, you must have passed by DataObjectTypeName property of the ObjectDataSource.
I have been working with it for a while, but thought of sharing with you the beauty of that property.

Usually, ObjectDataSource uses two modes to pass parameters for the data mapper's methods:

  • Simple Data Types (string, int, etc ...)
  • Custom Objects (Input for methods would be an object)

When you set the DataOjectTypeName ="MyClass" of the ObjectDataSource, then the following should be valid:

  • All CRUD (Create, Retrieve, Update, Delete) methods specified in the TypeName property of ObjectDataSource should expect a parameter of type "MyClass" as an input parameter, except for the Retrieve method for sure. For instance:
    public static void Delete(MyClass p_Myclass)
    { }
  • The MyClass is a simple object, that has some public properties like: ID, Name, Email, etc ... Make sure that the properties' names match exactly witht the names of the fields displayed by the Data-Bound Controls. For instance, if you have a property called ID in the MyClass, the GridView displaying the records, should have the name of the BoundField representing the ID as "ID", you see how names match?
  • No more needed to list all Select,Update,Insert,Delete parameters in the ObjectDataSource. At runtime, an instance of type MyClass is created for us out of the Data-Bound Control (example: GridView) and sent to the data mapper's methods!

I asked myself, wouldn't that be waste of time if I am sending the whole object to the Delete Method, in a time, I only need for example ID to delete a record? Well, the answer came back directly from the ObjectDataSource as follows: The proccess is so inteligent that when the Delete Button is clicked, the key specified in the DataKeyNames property of the GridView for example, is supplied to the MyClass instance, so only the ID is filled and the rest of fields are igonored. Isn't that great?

Check this simple example to see How Stuff Works ;)

GridView + ObjectDataSource       

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1">
            <Columns>
                <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
                <asp:BoundField ReadOnly="true" DataField="EmployeeId" HeaderText="EmployeeId" SortExpression="EmployeeId" />
                <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
            </Columns>
        </asp:GridView>
        &nbsp;</div>
        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="Employee"
            DeleteMethod="Delete" SelectMethod="Get" TypeName="EmployeeDal"></asp:ObjectDataSource>

Employee and EmployeeDal

public class Employee
{
    #region Private Members
    private int m_EmployeeId;
    private string m_FirstName;
    private string m_LastName;
    #endregion

    #region Constructors
    public Employee()
    { }

    public Employee(int p_EmployeeId, string p_FirstName, string p_LastName)
    {
        this.m_EmployeeId = p_EmployeeId;
        this.m_FirstName = p_FirstName;
        this.m_LastName = p_LastName;
    }
    #endregion

    #region Public Properties
    public int EmployeeId
    {
        get { return this.m_EmployeeId; }
        set { this.m_EmployeeId = value; }
    }

    public string FirstName
    {
        get { return this.m_FirstName; }
        set { this.m_FirstName = value; }
    }
    public string LastName
    {
        get { return this.m_LastName; }
        set { this.m_LastName = value; }
    }
    #endregion
}

--------------------

using System;
using System.Data;
using System.ComponentModel;
using System.Configuration;
using System.Collections.Generic;

[DataObjectAttribute]
public class EmployeeDal
{
    public EmployeeDal()
    {   }

    [DataObjectMethodAttribute(DataObjectMethodType.Delete, true)]
    public static void Delete(Employee p_Employee)
    {
        // your logic to delete a record using the parameter EmployeeId as follows
        int EmployeeId = p_Employee.EmployeeId;
    }
   
    [DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
    public List<Employee> Get()
    {
        // your logic to retrieve all records

        return new List<Employee>();
    }
}

Hope this helps,

Regards

Tags:

Apr 17 2006

ASP.NET 2.0 Localize Control

Category: ASP.NET 2.0 - GeneralBil@l @ 08:26

In my research on Localization in ASP.NET 2.0, which is my topic of the next Community Night Session at Microsoft Office in Beirut, I passed by the <asp:Localize> control in ASP.NET 2.0.

This control inherits from the Literal Control. It is mainly used to display static text on a web page that is to be localized.

You might say, a Literal or Label can do the job for me, that is true. BUT, both a Label and Literal control, don't have design view editing. So, using the Localize, you can write down the text on the spot through the design view of the page.

You can also, put some text into the Localize control programmatically same as you do with the Label and Literal Control.

However, styling of text is not allowed in a Localize control, as in the Label control. However, you can always hug the Localize control with a CSS class for formatting issues ;)

Hope this helps you,

Regards

Tags: