UpdatePanel controls work by specifying regions of a page that can be updated without refreshing the whole page. This process is coordinated by the ScriptManager server control and the client PageRequestManager class. When partial-page updates are enabled, controls can asynchronously post to the server. An asynchronous postback behaves like a regular postback in that the resulting server page executes the complete page and control life cycle. However, with an asynchronous postback, page updates are limited to regions of the page that are enclosed in UpdatePanel controls and that are marked to be updated. The server sends HTML markup for only the affected elements to the browser. In the browser, the client PageRequestManager class performs Document Object Model (DOM) manipulation to replace existing HTML with updated markup.
Note: |
|---|
When you are using asynchronous postbacks or using the
XMLHTTPRequest object, a postback error can occur if the URL contains a double-byte character. You can resolve this problem by including a <base href="url"/> element in the head element of the page, where the href attribute is set to the URL-encoded string that references the page. You can add this element added dynamically in server code.
|
The following illustration shows a page that is loaded for the first time, and a subsequent asynchronous postback that refreshes the content of an UpdatePanel control.
Partial-page rendering overview
.png)
Enabling Partial-Page Updates
The UpdatePanel control requires a ScriptManager control in the Web page. By default, partial-page updates are enabled because the default value of the EnablePartialRendering property of the ScriptManager control is true.
The following example shows markup that defines a ScriptManager control and an UpdatePanel control on a page. The UpdatePanel control contains a Button control that refreshes the content inside the panel when you click it. By default, the ChildrenAsTriggers property is true. Therefore, the Button control acts as an asynchronous postback control.
<asp:ScriptManager ID="ScriptManager"
runat="server" />
<asp:UpdatePanel ID="UpdatePanel1"
UpdateMode="Conditional"
runat="server">
<ContentTemplate>
<fieldset>
<legend>UpdatePanel content</legend>
<!-- Other content in the panel. -->
<%=DateTime.Now.ToString() %>
<br />
<asp:Button ID="Button1"
Text="Refresh Panel"
runat="server" />
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
<asp:ScriptManager ID="ScriptManager"
runat="server" />
<asp:UpdatePanel ID="UpdatePanel1"
UpdateMode="Conditional"
runat="server">
<ContentTemplate>
<fieldset>
<legend>UpdatePanel content</legend>
<!-- Other content in the panel. -->
<%=DateTime.Now.ToString() %>
<br />
<asp:Button ID="Button1"
Text="Refresh Panel"
runat="server" />
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
Specifying UpdatePanel Control Content
You add content to an UpdatePanel control declaratively or in the designer by using the ContentTemplate property. In markup, this property is exposed as a ContentTemplate element. To add content programmatically, you use the ContentTemplateContainer property.
When a page that contains one or more UpdatePanel controls is first rendered, all the contents of the UpdatePanel controls are rendered and sent to the browser. On subsequent asynchronous postbacks, the content of individual UpdatePanel controls might be updated. Updates depend on the panel settings, on what element caused the postback, and on code that is specific to each panel.
Specifying UpdatePanel Triggers
By default, any postback control inside an UpdatePanel control causes an asynchronous postback and refreshes the panel's content. However, you can also configure other controls on the page to refresh an UpdatePanel control. You do this by defining a trigger for the UpdatePanel control. A trigger is a binding that specifies which postback control and event cause a panel to update. When the specified event of the trigger control is raised (for example, a button's Click event), the update panel is refreshed.
The following example shows how to specify a trigger for an UpdatePanel control.
<asp:Button ID="Button1"
Text="Refresh Panel"
runat="server" />
<asp:ScriptManager ID="ScriptManager1"
runat="server" />
<asp:UpdatePanel ID="UpdatePanel1"
UpdateMode="Conditional"
runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" />
</Triggers>
<ContentTemplate>
<fieldset>
<legend>UpdatePanel content</legend>
<%=DateTime.Now.ToString() %>
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="Button1"
Text="Refresh Panel"
runat="server" />
<asp:ScriptManager ID="ScriptManager1"
runat="server" />
<asp:UpdatePanel ID="UpdatePanel1"
UpdateMode="Conditional"
runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" />
</Triggers>
<ContentTemplate>
<fieldset>
<legend>UpdatePanel content</legend>
<%=DateTime.Now.ToString() %>
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
The trigger is defined by using the asp:AsyncPostBackTrigger element inside the Triggers element of the UpdatePanel control. (If you are editing the page in Visual Studio, you can create triggers by using the UpdatePanelTrigger Collection Editor dialog box.)
A trigger's control event is optional. If you do not specify an event, the trigger event is the default event of the control. For example, for the Button control, the default event is the Click event.
How UpdatePanel Controls Are Refreshed
The following list describes the property settings of the UpdatePanel control that determine when a panel's content is updated during partial-page rendering.
If the UpdateMode property is set to Always, the UpdatePanel control’s content is updated on every postback that originates from anywhere on the page. This includes asynchronous postbacks from controls that are inside other UpdatePanel controls, and postbacks from controls that are not inside UpdatePanel controls.
If the UpdateMode property is set to Conditional, the UpdatePanel control’s content is updated when one of the following is true:
When the postback is caused by a trigger for that UpdatePanel control.
When you explicitly call the UpdatePanel control's Update method.
When the UpdatePanel control is nested inside another UpdatePanel control and the parent panel is updated.
When the ChildrenAsTriggers property is set to true and any child control of the UpdatePanel control causes a postback. Child controls of nested UpdatePanel controls do not cause an update to the outer UpdatePanel control unless they are explicitly defined as triggers for the parent panel.
If the ChildrenAsTriggers property is set to false and the UpdateMode property is set to Always, an exception is thrown. The ChildrenAsTriggers property is intended to be used only when the UpdateMode property is set to Conditional.
Using UpdatePanel Controls in Master Pages
To use an UpdatePanel control in a master page, you must decide how to include the ScriptManager control. If you include the ScriptManager control on the master page, it can act as the ScriptManager control for all content pages. (If you want to register scripts or services declaratively in a content page, you can add a ScriptManagerProxy control to that content page.)
If the master page does not contain the ScriptManager control, you can put the ScriptManager control individually on each content page that contains an UpdatePanel control. The design choice depends on how you intend to manage client script in your application. For more information about how to manage client script, see ScriptManager Control Overview. For more information about master pages, see ASP.NET Master Pages Overview.
In some cases, the ScriptManager control is on the master page and you do not need partial-page rendering capabilities for a content page. In those cases, you must programmatically set the EnablePartialRendering property of the ScriptManager control to false for that content page.
The following example shows markup for a ScriptManager control on the master page and an UpdatePanel control on a content page. In this example, a property named LastUpdate is defined on the master page and is referenced from inside the UpdatePanel control.
<%@ Master Language="VB" %>
<!DOCTYPE html PUBLIC "-'W3C'DTD XHTML 1.0 Transitional'EN"
"http:'www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Public Property LastUpdate() As DateTime
Get
If ViewState("LastUpdate") Is Nothing Then
Return DateTime.Now
Else : Return ViewState("LastUpdate")
End If
End Get
Set(ByVal value As DateTime)
ViewState("LastUpdate") = value
End Set
End Property
Protected Sub MasterButton2_Click(ByVal Sender As Object, ByVal E As EventArgs)
LastUpdate = DateTime.Now
Dim up1 As UpdatePanel
up1 = ContentPlaceHolder1.FindControl("UpdatePanel1")
up1.Update()
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
ScriptManager1.RegisterAsyncPostBackControl(Button2)
End Sub
</script>
<html >
<head id="Head1" runat="server">
<title>ScriptManager in Master Page Example</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Panel ID="MasterPanel1" runat="server" GroupingText="Master Page">
<asp:Button ID="Button1" runat="server" Text="Full Page Refresh" />
<asp:Button ID="Button2" runat="server" Text="Refresh Panel" OnClick="MasterButton2_Click" />
</asp:Panel>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
<%@ Master Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
public DateTime LastUpdate
{
get
{
return (DateTime)(ViewState["LastUpdate"] ?? DateTime.Now);
}
set
{
ViewState["LastUpdate"] = value;
}
}
protected void MasterButton2_Click(object sender, EventArgs e)
{
LastUpdate = DateTime.Now;
((UpdatePanel)ContentPlaceHolder1.FindControl("UpdatePanel1")).Update();
}
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager1.RegisterAsyncPostBackControl(Button2);
}
</script>
<html >
<head id="Head1" runat="server">
<title>ScriptManager in Master Page Example</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Panel ID="MasterPanel1" runat="server" GroupingText="Master Page">
<asp:Button ID="Button1" runat="server" Text="Full Page Refresh" />
<asp:Button ID="Button2" runat="server" Text="Refresh Panel" OnClick="MasterButton2_Click" />
</asp:Panel>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
<%@ Page Language="VB" MasterPageFile="MasterVB.master"
Title="ScriptManager in Content Page" %>
<%@ MasterType VirtualPath="MasterVB.master" %>
<script runat="server">
Protected Sub Button3_Click(ByVal Sender As Object, ByVal E As EventArgs)
Master.LastUpdate = DateTime.Now
End Sub
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
runat="Server">
</asp:ScriptManagerProxy>
<asp:Panel ID="Panel2"
GroupingText="ContentPage"
runat="server" >
<asp:UpdatePanel ID="UpdatePanel1"
UpdateMode="Conditional"
runat="server">
<ContentTemplate>
<p>
Last updated: <strong>
<%= Master.LastUpdate.ToString() %>
</strong>
</p>
<asp:Button ID="Button3"
Text="Refresh Panel"
OnClick="Button3_Click"
runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
</asp:Content>
<%@ Page Language="C#" MasterPageFile="MasterCS.master"
Title="ScriptManager in Content Page" %>
<%@ MasterType VirtualPath="MasterCS.master" %>
<script runat="server">
protected void Button3_Click(object sender, EventArgs e)
{
Master.LastUpdate = DateTime.Now;
}
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
runat="Server">
<asp:Panel ID="Panel2"
GroupingText="ContentPage"
runat="server" >
<asp:UpdatePanel ID="UpdatePanel1"
UpdateMode="Conditional"
runat="server">
<ContentTemplate>
<p>
Last updated: <strong>
<%= Master.LastUpdate.ToString() %>
</strong>
</p>
<asp:Button ID="Button3"
Text="Refresh Panel"
OnClick="Button3_Click"
runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
</asp:Content>
Using Nested UpdatePanel Controls
UpdatePanel controls can be nested. If the parent panel is refreshed, all nested panels are refreshed also.
The following example shows markup that defines an UpdatePanel control inside another UpdatePanel control. A button in the parent panel triggers an update of the content in both the parent and the child panel. The button in the child panel triggers an update of only the child panel.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html >
<head id="Head1" runat="server">
<title>UpdatePanelUpdateMode Example</title>
<style type="text/css">
div.NestedPanel
{
position: relative;
margin: 2% 5% 2% 5%;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager"
runat="server" />
<asp:UpdatePanel ID="OuterPanel"
UpdateMode="Conditional"
runat="server">
<ContentTemplate>
<div>
<fieldset>
<legend>Outer Panel </legend>
<br />
<asp:Button ID="OPButton1"
Text="Outer Panel Button"
runat="server" />
<br />
Last updated on
<%= DateTime.Now.ToString() %>
<br />
<br />
<asp:UpdatePanel ID="NestedPanel1"
UpdateMode="Conditional"
runat="server">
<ContentTemplate>
<div class="NestedPanel">
<fieldset>
<legend>Nested Panel 1</legend>
<br />
Last updated on
<%= DateTime.Now.ToString() %>
<br />
<asp:Button ID="NPButton1"
Text="Nested Panel 1 Button"
runat="server" />
</fieldset>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</fieldset>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html >
<head id="Head1" runat="server">
<title>UpdatePanelUpdateMode Example</title>
<style type="text/css">
div.NestedPanel
{
position: relative;
margin: 2% 5% 2% 5%;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager"
runat="server" />
<asp:UpdatePanel ID="OuterPanel"
UpdateMode="Conditional"
runat="server">
<ContentTemplate>
<div>
<fieldset>
<legend>Outer Panel </legend>
<br />
<asp:Button ID="OPButton1"
Text="Outer Panel Button"
runat="server" />
<br />
Last updated on
<%= DateTime.Now.ToString() %>
<br />
<br />
<asp:UpdatePanel ID="NestedPanel1"
UpdateMode="Conditional"
runat="server">
<ContentTemplate>
<div class="NestedPanel">
<fieldset>
<legend>Nested Panel 1</legend>
<br />
Last updated on
<%= DateTime.Now.ToString() %>
<br />
<asp:Button ID="NPButton1"
Text="Nested Panel 1 Button"
runat="server" />
</fieldset>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</fieldset>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
The following example shows a nested UpdatePanel control with a GridView control. The GridView control is inside an UpdatePanel control, and each GridView row contains a nested GridView control inside another UpdatePanel control.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html >
<head runat="server">
<title>Browse Departments</title>
<script runat="server">
Protected Sub DepartmentsGridView_RowDataBound(sender As object, e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim s As SqlDataSource = CType(e.Row.FindControl("EmployeesDataSource"), SqlDataSource)
Dim r As System.Data.DataRowView = CType(e.Row.DataItem, System.Data.DataRowView)
s.SelectParameters("DepartmentID").DefaultValue = r("DepartmentID").ToString()
End If
End Sub
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" ID="ScriptManager1" EnablePartialRendering="true" />
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="DepartmentsGridView" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" CellPadding="4" DataSourceID="DepartmentDataSource"
ForeColor="#333333" GridLines="None" PageSize="3" OnRowDataBound="DepartmentsGridView_RowDataBound">
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<Columns>
<asp:BoundField DataField="GroupName" HeaderText="Division" SortExpression="GroupName" >
<ItemStyle Width="200px" />
</asp:BoundField>
<asp:BoundField DataField="Name" HeaderText="Department Name" SortExpression="Name" >
<ItemStyle Width="160px" />
</asp:BoundField>
<asp:TemplateField HeaderText="Employees">
<ItemTemplate>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="EmployeesGridView" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" BackColor="White" BorderColor="#999999" BorderStyle="None"
BorderWidth="1px" CellPadding="3" DataSourceID="EmployeesDataSource" GridLines="Vertical"
PageSize="4">
<FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" >
<ItemStyle Width="80px" />
</asp:BoundField>
<asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName" >
<ItemStyle Width="160px" />
</asp:BoundField>
</Columns>
<RowStyle BackColor="#EEEEEE" ForeColor="Black" />
<SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="Gainsboro" />
</asp:GridView>
<asp:Label runat="server" ID="InnerTimeLabel"><%=DateTime.Now %></asp:Label>
<asp:SqlDataSource ID="EmployeesDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
SelectCommand="SELECT HumanResources.EmployeeDepartmentHistory.DepartmentID,
HumanResources.vEmployee.EmployeeID,
HumanResources.vEmployee.FirstName,
HumanResources.vEmployee.LastName
FROM HumanResources.EmployeeDepartmentHistory
INNER JOIN HumanResources.vEmployee
ON HumanResources.EmployeeDepartmentHistory.EmployeeID = HumanResources.vEmployee.EmployeeID
WHERE HumanResources.EmployeeDepartmentHistory.DepartmentID = @DepartmentID
ORDER BY HumanResources.vEmployee.LastName ASC, HumanResources.vEmployee.FirstName ASC">
<SelectParameters>
<asp:Parameter Name="DepartmentID" DefaultValue="0" Type="int32" />
</SelectParameters>
</asp:SqlDataSource>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
<ItemStyle Height="170px" Width="260px" />
</asp:TemplateField>
</Columns>
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" VerticalAlign="Top" />
<EditRowStyle BackColor="#999999" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" VerticalAlign="Top" />
</asp:GridView>
<asp:Label runat="server" ID="OuterTimeLabel"><%=DateTime.Now %></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<asp:SqlDataSource ID="DepartmentDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
SelectCommand="SELECT DepartmentID, Name, GroupName FROM HumanResources.Department ORDER BY Name">
</asp:SqlDataSource>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html >
<head runat="server">
<title>Browse Departments</title>
<script runat="server">
protected void DepartmentsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
SqlDataSource s = (SqlDataSource)e.Row.FindControl("EmployeesDataSource");
System.Data.DataRowView r = (System.Data.DataRowView)e.Row.DataItem;
s.SelectParameters["DepartmentID"].DefaultValue = r["DepartmentID"].ToString();
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" ID="ScriptManager1" EnablePartialRendering="true" />
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="DepartmentsGridView" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" CellPadding="4" DataSourceID="DepartmentDataSource"
ForeColor="#333333" GridLines="None" PageSize="3" OnRowDataBound="DepartmentsGridView_RowDataBound">
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<Columns>
<asp:BoundField DataField="GroupName" HeaderText="Division" SortExpression="GroupName" >
<ItemStyle Width="200px" />
</asp:BoundField>
<asp:BoundField DataField="Name" HeaderText="Department Name" SortExpression="Name" >
<ItemStyle Width="160px" />
</asp:BoundField>
<asp:TemplateField HeaderText="Employees">
<ItemTemplate>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="EmployeesGridView" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" BackColor="White" BorderColor="#999999" BorderStyle="None"
BorderWidth="1px" CellPadding="3" DataSourceID="EmployeesDataSource" GridLines="Vertical"
PageSize="4">
<FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" >
<ItemStyle Width="80px" />
</asp:BoundField>
<asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName" >
<ItemStyle Width="160px" />
</asp:BoundField>
</Columns>
<RowStyle BackColor="#EEEEEE" ForeColor="Black" />
<SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="Gainsboro" />
</asp:GridView>
<asp:Label runat="server" ID="InnerTimeLabel"><%=DateTime.Now %></asp:Label>
<asp:SqlDataSource ID="EmployeesDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
SelectCommand="SELECT HumanResources.EmployeeDepartmentHistory.DepartmentID,
HumanResources.vEmployee.EmployeeID,
HumanResources.vEmployee.FirstName,
HumanResources.vEmployee.LastName
FROM HumanResources.EmployeeDepartmentHistory
INNER JOIN HumanResources.vEmployee
ON HumanResources.EmployeeDepartmentHistory.EmployeeID = HumanResources.vEmployee.EmployeeID
WHERE HumanResources.EmployeeDepartmentHistory.DepartmentID = @DepartmentID
ORDER BY HumanResources.vEmployee.LastName ASC, HumanResources.vEmployee.FirstName ASC">
<SelectParameters>
<asp:Parameter Name="DepartmentID" DefaultValue="0" Type="int32" />
</SelectParameters>
</asp:SqlDataSource>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
<ItemStyle Height="170px" Width="260px" />
</asp:TemplateField>
</Columns>
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" VerticalAlign="Top" />
<EditRowStyle BackColor="#999999" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" VerticalAlign="Top" />
</asp:GridView>
<asp:Label runat="server" ID=