Beginning ASP.NET 1.1 with Visual C# .NET 1002003 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Beginning ASP.NET 1.1 with Visual C# .NET 1002003 [Electronic resources] - نسخه متنی

Chris Ullman

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید











Chapter 10

This chapter explains how ASP.NET server controls derive their properties and methods from the various classes and objects that make up the .NET Framework. This chapter is where you see the Wrox United application taking shape.


Exercise 1


Consider a use for an HTML tag with

runat="server" in the Wrox United application in place of one of the existing Web controls and explain why the HTML control is able to achieve the same result as the Web control.

Solution


You can make this change in several places in

Default.aspx – for example, the

asp:Hyperlink

controls could be replaced with HTML anchor tags with a

runat="server" attribute. You could also change the panel which displays match details and replaces it with a

<div> tag:


<div id="pnlFixtureDetails" runat="server" visible="false">
<asp:Repeater id="MatchesByDateList" runat="server">
<headertemplate>
...
</headertemplate>
<itemtemplate>
...
</itemtemplate>
<separatortemplate>
...
</separatortemplate>
</asp:Repeater>

</div>


This works because the only property of the

Panel control used in this example is the

Visible

property; a property that is available to all server controls, including HTML controls. A

<div> is a direct replacement for a

Panel in this case.


Exercise 2


Add another event handler to the

Teams.aspx page that reacts to the selection of a player's name and takes the reader to the

Players.aspx page.

Solution


Add the following event-handling code to

Players.aspx :


void PlayersList_ItemCommand(object sender, RepeaterCommandEventArgs e)

{

if(e.CommandName == "ShowPlayers")

{

Response.Redirect("Players.aspx");

}

}


Change the HTML as follows:

<asp:Repeater id="PlayersList" runat="server" 
OnItemCommand="PlayersList_ItemCommand">
<ItemTemplate>
<asp:linkbutton
text='<%# DataBinder.Eval(Container.DataItem, "PlayerName") %>'
style="color:darkred"

runat="server" width="120" CommandName="ShowPlayers" />
&nbsp;&nbsp;
<asp:Label
text='<%# DataBinder.Eval(Container.DataItem, "PositionName") %>'
id="playerposition" runat="server" />
<br />
</ItemTemplate>
<headerTemplate>
Players in: <%= selectedTeam %>
<hr color="#b0c4de" width="250px" />
</headerTemplate>
<footerTemplate>
<hr color="#b0c4de" width="250px" />
</footerTemplate>
</asp:Repeater>



Exercise 3


Amend the code in

Default.aspx so that if a user selects a date in the calendar for which there are no matches, nothing is displayed in the panel.

Solution


There are two ways you can achieve this result. The first of these is to modify the

EventCalendar_SelectionChanged() event handler as follows:

public void EventCalendar_SelectionChanged(object sender, EventArgs e)
{

if (DateList[EventCalendar.SelectedDate] != null)
{
MatchesByDateList.DataSource = GamesByDate(EventCalendar.SelectedDate);
pnlFixtureDetails.Visible = true;
MatchesByDateList.DataBind();
}

else

{

pnlFixtureDetails.Visible = false;

}
}


Alternatively, you can change how non-match days are rendered in the calendar:

public void EventCalendar_DayRender(object sender, DayRenderEventArgs e) 
{
if (DateList[e.Day.Date] != null)
{
e.Cell.Style.Add("font-weight", "bold");
e.Cell.Style.Add("font-size", "larger");
e.Cell.Style.Add("border", "3 dotted darkred");
e.Cell.Style.Add("background", "#f0f0f0");

// ensure match dates are hyperlinks

e.Day.IsSelectable = true;
}
else
{
e.Cell.Style.Add("font-weight", "lighter");
e.Cell.Style.Add("color", "DimGray");

// ensure non-match dates are not selectable

e.Day.IsSelectable = false;
}
}


Using the

IsSelectable property, we can control whether or not a date is selectable. Setting this to

false means that non-match days are not rendered as hyperlinks and therefore, will cause the panel to not be displayed. The code in the following chapters uses this property to achieve this result.


Exercise 4


Have a go at customizing

Players.aspx : change the field that displays the name of the player into a hyperlink that, when clicked, will reveal a panel lower down on the page that lists the team or teams that the selected player is a member of. You will find that the

Fields editor of the

MxDataGrid is very useful for this (select the

Fields property builder when you are in the Design view). You need to ensure that the clicking of the player name is handled correctly. You also need to add another method to extract team information (you may find that the

DataReader that returns the list of teams from the

Teams.aspx page is useful here).

Solution


First, we need to change the

BoundField into a

ButtonField :

<Fields>
<wmx:BoundField Visible="False" DataField="PlayerID"></wmx:BoundField>

<wmx:ButtonField DataTextField="PlayerName"

HeaderText="Name" CommandName="ShowPlayer"></wmx:ButtonField>
<wmx:BoundField DataField="Profile" HeaderText="Profile"></wmx:BoundField>
<wmx:BoundField DataField="JoinDate" HeaderText="Join Date"
DataFormatString="{0:d}"></wmx:BoundField>
</Fields>


Notice we set a

CommandName property on the field as well to be able to intercept and handle commands. Let's now add a repeater that will show the teams for a particular player:


<p>

<asp:Repeater id="TeamList" runat="server" Visible="False">

<ItemTemplate>

<asp:Label

style="color:darkred"

text='<%# DataBinder.Eval(Container.DataItem, "TeamName") %>'

runat="server" width="120" />

&nbsp;&nbsp;

<asp:Label

text='<%# DataBinder.Eval(Container.DataItem, "PositionName") %>'

id="playerposition"

runat="server" />

<br />

</ItemTemplate>

<headerTemplate>

<%= selectedPlayer %>'s Teams:

<hr color="#b0c4de" width="250px" />

</headerTemplate>

<footerTemplate>

<hr color="#b0c4de" width="250px" />

</footerTemplate>

</asp:Repeater>

</p>


The resultant page looks almost identical to the repeater from the

Team page.

We also need to tell the

DataGrid that we'll be writing an

ItemCommand() event handler for it:

<wmx:MxDataGrid id="MxDataGrid1" runat="server" 
BorderStyle="None"
BorderWidth="1px"
DataKeyField="PlayerID"
CellPadding="3"
BackColor="White"
AllowPaging="True"
DataMember="Players"
AllowSorting="True"
BorderColor="#CCCCCC"
DataSourceControlID="AccessDataSourceControl1"
AutoGenerateFields="False"

OnItemCommand="MxDataGrid1_ItemCommand">


Now, in the Code view, we need to change the whole page script:


private string selectedPlayer;

void Page_Load()

{

Page.DataBind();

}

private void MxDataGrid1_ItemCommand(object sender,

MxDataGridCommandEventArgs e)

{

if (e.CommandName.Equals("ShowPlayer"))

{

LinkButton thing = (LinkButton)e.CommandSource;

selectedPlayer = thing.Text;

TableCell cell = (TableCell)e.Item.Controls[0];

int SelectedPlayerID = int.Parse(cell.Text);

TeamList.DataSource = GetTeamsByPlayer(SelectedPlayerID);

TeamList.DataBind();

TeamList.Visible = true;

}

else

{

TeamList.Visible = false;

}

}

private System.Data.IDataReader GetTeamsByPlayer(int playerID)

{

string connectionString =

ConfigurationSettings.AppSettings["ConnectionString"];

System.Data.IDbConnection dbConnection =

new System.Data.OleDb.OleDbConnection(connectionString);

string queryString = "SELECT

[Players].[PlayerName],[Positions].[PositionName],[Teams].[TeamName]

FROM [Players], [Positions], [PlayerTeam], [Teams]

WHERE (([PlayerTeam].[PlayerID] = [Players].[PlayerID])

AND ([PlayerTeam].[Position] = [Positions].[PositionID])

AND ([PlayerTeam].[TeamID] = [Teams].[TeamID])

AND ([Players].[PlayerID] = @PlayerID))";

System.Data.IDbCommand dbCommand = new System.Data.OleDb.OleDbCommand();

dbCommand.CommandText = queryString;

dbCommand.Connection = dbConnection;

System.Data.IDataParameter dbParam_teamID =

new System.Data.OleDb.OleDbParameter();

dbParam_teamID.ParameterName = "@PlayerID";

dbParam_teamID.Value = playerID;

dbParam_teamID.DbType = System.Data.DbType.Int32;

dbCommand.Parameters.Add(dbParam_teamID);

dbConnection.Open();

System.Data.IDataReader dataReader =

dbCommand.ExecuteReader(System.Data.CommandBehavior.CloseConnection);

return dataReader;

}


The

GetTeamsByPlayer() method is a very simple alteration of

GetPlayersByTeam() from the

Teams

page. The really tricky part on this page is that we need to obtain the ID of the player that the user selects. In the

Team page, that was easy – we packaged up each team's ID as the

CommandArgument for the

LinkButton in the teams

DataList . But a

DataGrid won't let us do that, so we need to find another solution. Remember the fields we set up on the players

DataGrid ? At the left hand side there was an invisible column that contained the player ID. This is how we get it:


TableCell cell = (TableCell)e.Item.Controls[0];

int SelectedPlayerID = int.Parse(cell.Text);


/ 220