Share via


マスター ページとサイト ナビゲーション (C#)

作成者: Scott Mitchell

PDF のダウンロード

ユーザーフレンドリな Web サイトに共通する特徴の 1 つは、サイト全体のページ レイアウトとナビゲーション スキームが一貫していることです。 このチュートリアルでは、すべてのページで一貫した簡単に更新できる外観を作成する方法について確認します。

はじめに

ユーザーフレンドリな Web サイトに共通する特徴の 1 つは、サイト全体のページ レイアウトとナビゲーション スキームが一貫していることです。 ASP.NET 2.0 では、サイト全体のページ レイアウトとナビゲーション スキームの実装を大幅に簡略化する 2 つの新機能であるマスター ページとサイト ナビゲーションが導入されています。 マスター ページを使用すると、開発者は指定された編集可能な領域を使用するサイト全体のテンプレートを作成できます。 その後、このテンプレートをサイト内の ASP.NET ページに適用することができます。 このような ASP.NET ページで提供する必要があるのは、マスター ページの指定された編集可能な領域のコンテンツだけであり、マスター ページ内の他のすべてのマークアップは、マスター ページを使用するすべての ASP.NET ページで同一のものです。 このモデルを使用すると、開発者はサイト全体のページ レイアウトを定義して一元化できるため、すべてのページで一貫した簡単に更新できる外観を簡単に作成できます。

サイト ナビゲーション システムは、ページ開発者がサイト マップを定義するメカニズムと、そのサイト マップ用の API の両方を提供します。 新しいナビゲーション Web は、Menu、TreeView、SiteMapPath を制御し、共通のナビゲーション ユーザー インターフェイス要素内でサイト マップのすべてまたは一部を簡単にレンダリングできるようにします。 以下では既定のサイト ナビゲーション プロバイダーを使用します。つまり、サイト マップは XML 形式のファイルで定義されることになります。

これらの概念を明らかにし、このチュートリアル Web サイトをより使いやすくするために、このレッスンでは、サイト全体のページ レイアウトの定義、サイト マップの実装、ナビゲーション UI の追加を行います。 このチュートリアルを完了すると、チュートリアル Web ページを構築するための洗練された Web サイト デザインが完成します。

The End Result of This Tutorial

図 1: このチュートリアルの最終結果 (フルサイズ画像を表示するにはこちらをクリックしてください)

手順 1: マスター ページの作成

最初の手順は、サイトのマスター ページを作成することです。 現時点で、この Web サイトは、型指定されたデータセット (App_Code フォルダー内の Northwind.xsd)、BLL クラス (ProductsBLL.csCategoriesBLL.cs など。すべて App_Code フォルダー内に含まれています)、データベース (App_Data フォルダー内の NORTHWND.MDF)、構成ファイル (Web.config)、CSS スタイルシート ファイル (Styles.css) から構成されています。 最初の 2 つのチュートリアルから DAL と BLL の使用のデモを行うページとファイルを削除しました。これらの例については今後のチュートリアルで再度さらに詳しく確認します。

The Files in Our Project

図 2: プロジェクト内のファイル

マスター ページを作成するには、ソリューション エクスプローラーでプロジェクト名を右クリックし、[新しい項目の追加] を選択します。 次に、テンプレートの一覧からマスター ページ タイプを選択し、それに Site.master という名前を付けます。

Add a New Master Page to the Website

図 3: Web サイトに新しいマスター ページを追加する (フルサイズ画像を表示するにはこちらをクリックしてください)

サイト全体のページ レイアウトは、このマスター ページ内で定義します。 デザイン ビューを使用して、必要なレイアウト コントロールや Web コントロールを追加したり、ソース ビューで手動でマークアップを追加したりできます。 このマスター ページでは、配置とスタイル用のカスケード スタイル シートに、外部ファイル Style.css 内で定義された CSS 設定を使用しています。 以下に示すマークアップからは分かりませんが、CSS ルールは、ナビゲーション <div> のコンテンツが絶対位置指定され左側に固定幅 200 ピクセルで表示されるように定義されています。

Site.master

<%@ Master Language="C#" AutoEventWireup="true"
    CodeFile="Site.master.cs" Inherits="Site" %>

<!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 runat="server">
    <title>Working with Data Tutorials</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div id="wrapper">

        <form id="form1" runat="server">

            <div id="header">
                <span class="title">Working with Data Tutorials</span>
                <span class="breadcrumb">
                 TODO: Breadcrumb will go here...</span>
            </div>

            <div id="content">
                <asp:contentplaceholder id="MainContent"
                 runat="server">
                  <!-- Page-specific content will go here... -->
                </asp:contentplaceholder>
            </div>

            <div id="navigation">
                TODO: Menu will go here...
            </div>
        </form>
    </div>
</body>
</html>

マスター ページは、静的なページ レイアウトとそのマスター ページを使用する ASP.NET ページによって編集可能な領域の両方を定義します。 これらのコンテンツの編集可能な領域は、コンテンツ <div> 内で確認できる ContentPlaceHolder コントロールによって示されます。 このマスター ページが持つ ContentPlaceHolder (MainContent) は 1 つですが、マスター ページは複数の ContentPlaceHolder を持つことができます。

上記のマークアップを入力すると、デザイン ビューへの切り替えによってマスター ページのレイアウトが表示されます。 このマスター ページを使用するすべての ASP.NET ページが、この統一されたレイアウトと、MainContent 領域のマークアップを指定するための機能を持つことになります。

The Master Page, When Viewed Through the Design View

図 4: デザイン ビューを通して表示されたマスター ページ (フルサイズ画像を表示するにはこちらをクリックしてください)

手順 2: Web サイトへのホームページの追加

マスター ページを定義したことで、Web サイトに対して ASP.NET ページを追加する準備が整いました。 このウェブサイトのホームページである Default.aspx の追加から始めましょう。 ソリューション エクスプローラーでプロジェクト名を右クリックし、[新しい項目の追加] を選択します。 テンプレートの一覧から Web フォーム オプションを選択し、ファイルに Default.aspx という名前を付けます。 また、"マスター ページの選択" チェックボックスをオンにします。

Add a New Web Form, Checking the Select master page Checkbox

図 5: [マスター ページの選択] チェックボックスをオンにして、新しい Web フォームを追加する (フルサイズ画像を表示するにはこちらをクリックしてください)

[OK] ボタンをクリックすると、この新しい ASP.NET ページがどのマスター ページを使用するべきかを選択するように求められます。 プロジェクトには複数のマスター ページを含めることができますが、ここでは 1 つしかありません。

Choose the Master Page this ASP.NET Page Should Use

図 6: この ASP.NET ページが使用するべきマスター ページを選択する (フルサイズ画像を表示するにはこちらをクリックしてください)

マスター ページを選択すると、新しい ASP.NET ページには以下のマークアップが含まれるようになります。

Default.aspx

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
  Runat="Server">
</asp:Content>

@Page ディレクティブ内には、使用されるマスター ページ ファイルへの参照 (MasterPageFile="~/Site.master") があり、ASP.NET ページのマークアップは、マスター ページで定義された各 ContentPlaceHolder コントロールに対する Content コントロールと、その Content コントロールを特定の ContentPlaceHolder にマップするコントロールの ContentPlaceHolderID を含んでいます。 Content コントロールは、対応する ContentPlaceHolder 内に表示させたいマークアップを配置する場所です。 以下のように、@Page ディレクティブの Title 属性を Home に設定し、Content コントロールに何らかのウェルカム コンテンツを追加します。

Default.aspx

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeFile="Default.aspx.cs" Inherits="_Default" Title="Home" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
    Runat="Server">
    <h1>Welcome to the Working with Data Tutorial Site</h1>

    <p>This site is being built as part of a set of tutorials that
illustrate some of the new data access and databinding features in
ASP.NET 2.0 and Visual Web Developer.</p>

    <p>Over time, it will include a host of samples that
demonstrate:</p>

    <ul>
        <li>Building a DAL (data access layer),</li>
        <li>Using strongly typed TableAdapters and DataTables</li>
        <li>Master-Detail reports</li>
        <li>Filtering</li>
        <li>Paging,</li>
        <li>Two-way databinding,</li>
        <li>Editing,</li>
        <li>Deleting,</li>
        <li>Inserting,</li>
        <li>Hierarchical data browsing,</li>
        <li>Hierarchical drill-down,</li>
        <li>Optimistic concurrency,</li>
        <li>And more!</li>
    </ul>
</asp:Content>

<title> 要素がマスター ページ内で定義されていますが、@Page ディレクティブ内で Title 属性を使用することで、ASP.NET ページからページのタイトルを設定できます。 Page.Title を使用して、プログラムでタイトルを設定することもできます。 また、マスター ページのスタイルシートへの参照 (Style.css など) は、それらがどのような ASP.NET ページ内にあっても、その ASP.NET ページが含まれるディレクトリのマスター ページから相対的に見た位置に関係なく動作するように、自動的に更新されることに注意してください。

デザイン ビューに切り替えることで、このページがブラウザー内でどのように表示されるかを確認できます。 ASP.NET ページのデザイン ビュー内で編集可能なのはコンテンツの編集可能な領域だけであり、マスター ページ内で定義されている ContentPlaceHolder 以外のマークアップはグレーアウトされていることに注意してください。

The Design View for the ASP.NET Page Shows Both the Editable and Non-Editable Regions

図 7: 編集可能な領域と編集不可能な領域の両方が表示されている ASP.NET ページのデザイン ビュー (フルサイズ画像を表示するにはこちらをクリックしてください)

Default.aspx ページがブラウザーによってアクセスされると、ASP.NET エンジンはページのマスター ページ コンテンツと ASP.NET のコンテンツを自動的にマージし、そのマージされたコンテンツを、要求を行っているブラウザーに送信される最終的な HTML にレンダリングします。 マスター ページのコンテンツが更新されると、このマスター ページを使用するすべての ASP.NET ページは、次回それらが要求されたときに自身のコンテンツを新しいマスター ページ コンテンツと再マージさせます。 つまり、マスター ページ モデルは、その変更がサイト全体にすぐに反映される単一のページ レイアウト テンプレート (マスター ページ) を定義することを可能にします。

Web サイトへのその他の ASP.NET ページの追加

次に、最終的にはさまざまなレポート デモを保持することになる ASP.NET ページ スタブをサイトに追加してみましょう。 デモの数は合計で 35 個になるため、すべてのスタブ ページを作成するのではなく、最初のいくつかだけを作成することにしましょう。 デモのカテゴリも多岐にわたるので、デモをより適切に管理するために、各カテゴリのフォルダーを追加します。 ここでは、以下の 3 つのフォルダーを追加します。

  • BasicReporting
  • Filtering
  • CustomFormatting

最後に、図 8 のソリューション エクスプローラーに示すように、新しいファイルを追加します。 各ファイルを追加する際には、"マスター ページの選択" チェックボックスをオンにすることを忘れないでください。

Add the Following Files

図 8: 以下のファイルを追加する

手順 2: サイト マップの作成

多数のページで構成される Web サイトを管理する際の課題の 1 つは、訪問者にサイト内を移動するための分かりやすい方法を提供することです。 まずは、サイトのナビゲーション構造を定義する必要があります。 次に、この構造をメニューや階層リンクなどの誘導可能なユーザー インターフェイス要素に変換する必要があります。 最後に、新しいページがサイトに追加されたり既存のページが削除された際に、このプロセス全体を保守して更新する必要があります。 ASP.NET 2.0 より前において、開発者はサイトのナビゲーション構造を作成し、保守し、誘導可能なユーザー インターフェイス要素に変換することを自分自身で行っていました。 しかし、ASP.NET 2.0 では、開発者は非常に柔軟な組み込みのサイト ナビゲーション システムを利用できます。

ASP.NET 2.0 サイト ナビゲーション システムは、開発者がサイト マップを定義し、プログラムの API を通してこの情報にアクセスするための手段を提供します。 ASP.NET にはサイト マップ プロバイダーが付属しており、これはサイト マップ データが特定の方法でフォーマット化された XML ファイルに保存されていることを想定しています。 しかし、サイト ナビゲーション システムはプロバイダー モデルに基づいて構築されているため、サイト マップ情報をシリアル化するための代替手段をサポートするように拡張できます。 Jeff Prosise による記事「待ち望まれてきた SQL サイト マップ プロバイダー」は、サイト マップを SQL Server データベース内に保存するサイト マップ プロバイダーを作成する方法を説明しています。もう 1 つの選択肢は、ファイル システム構造に基づくサイト マップ プロバイダーを作成することです。

ただし、このチュートリアルに関しては、ASP.NET 2.0 に付属する既定のサイト マップ プロバイダーを使用しましょう。 サイト マップを作成するには、ソリューション エクスプローラーでプロジェクト名を右クリックし、[新しい項目の追加] を選択し、[サイト マップ] オプションを選択するだけで済みます。 名前は Web.sitemap のままにして、[追加] ボタンをクリックします。

Add a Site Map to Your Project

図 9: プロジェクトにサイト マップを追加する (フルサイズ画像を表示するにはこちらをクリックしてください)

サイト マップ ファイルは XML ファイルです。 Visual Studio は、サイト マップ構造に対して IntelliSense を提供することに注意してください。 サイト マップ ファイルは、そのルート ノードとして <siteMap> ノードを持っている必要があり、これには 1 つだけの <siteMapNode> 子要素が含まれている必要があります。 その最初の <siteMapNode> 要素には、任意の数の子孫の <siteMapNode> 要素を含めることができます。

ファイル システム構造を模倣するサイト マップを定義します。 つまり、以下のように、3 つのフォルダーのそれぞれに対応する <siteMapNode> 要素と、それらのフォルダー内の各 ASP.NET ページに対応する <siteMapNode> 子要素を追加します。

Web.sitemap

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

  <siteMapNode url="~/Default.aspx" title="Home" description="Home">
      <siteMapNode title="Basic Reporting"
        url="~/BasicReporting/Default.aspx"
        description="Basic Reporting Samples">
        <siteMapNode url="~/BasicReporting/SimpleDisplay.aspx"
         title="Simple Display"
         description="Displays the complete contents
          of a database table." />
        <siteMapNode url="~/BasicReporting/DeclarativeParams.aspx"
          title="Declarative Parameters"
          description="Displays a subset of the contents
            of a database table using parameters." />
        <siteMapNode url="~/BasicReporting/ProgrammaticParams.aspx"
         title="Setting Parameter Values"
         description="Shows how to set parameter values
          programmatically." />
      </siteMapNode>

      <siteMapNode title="Filtering Reports"
       url="~/Filtering/Default.aspx"
       description="Samples of Reports that Support Filtering">
        <siteMapNode url="~/Filtering/FilterByDropDownList.aspx"
          title="Filter by Drop-Down List"
          description="Filter results using a drop-down list." />
        <siteMapNode url="~/Filtering/MasterDetailsDetails.aspx"
         title="Master-Details-Details"
         description="Filter results two levels down." />
        <siteMapNode url="~/Filtering/DetailsBySelecting.aspx"
          title="Details of Selected Row"
          description="Show detail results for a selected item in a GridView." />
      </siteMapNode>

      <siteMapNode title="Customized Formatting"
         url="~/CustomFormatting/Default.aspx"
         description="Samples of Reports Whose Formats are Customized">
        <siteMapNode url="~/CustomFormatting/CustomColors.aspx"
         title="Format Colors"
         description="Format the grid s colors based
           on the underlying data." />
        <siteMapNode
          url="~/CustomFormatting/GridViewTemplateField.aspx"
          title="Custom Content in a GridView"
          description="Shows using the TemplateField to
          customize the contents of a field in a GridView." />
        <siteMapNode
          url="~/CustomFormatting/DetailsViewTemplateField.aspx"
          title="Custom Content in a DetailsView"
          description="Shows using the TemplateField to customize
           the contents of a field in a DetailsView." />
        <siteMapNode url="~/CustomFormatting/FormView.aspx"
          title="Custom Content in a FormView"
          description="Illustrates using a FormView for a
           highly customized view." />
        <siteMapNode url="~/CustomFormatting/SummaryDataInFooter.aspx"
          title="Summary Data in Footer"
          description="Display summary data in the grids footer." />
      </siteMapNode>

  </siteMapNode>

</siteMap>

サイト マップは、Web サイトのナビゲーション構造を定義し、これはサイトのさまざまなセクションを記述する階層です。 Web.sitemap 内の各 <siteMapNode> 要素は、サイトのナビゲーション構造のセクションを表します。

The Site Map Represents a Hierarchical Navigational Structure

図 10: サイト マップは階層的ナビゲーション構造を表します (フルサイズ画像を表示するにはこちらをクリックしてください)

ASP.NET は、.NET Framework の SiteMap クラスを通してサイト マップの構造を公開します。 このクラスは CurrentNode プロパティを持っており、これはユーザーが現在アクセスしているセクションに関する情報を返します。RootNode プロパティは、サイト マップのルート (このサイト マップではホーム) を返します。 CurrentNode および RootNode プロパティは両方とも SiteMapNode インスタンスを返し、これはサイト マップ階層内の移動を可能にする ParentNodeChildNodesNextSiblingPreviousSibling などのプロパティを持っています。

手順 3: サイト マップに基づいたメニューの表示

ASP.NET 2.0 におけるデータへのアクセスは、ASP.NET 1.x においてと同様にプログラムによって実行することも、新しいデータ ソース コントロールを通して宣言によって実行することもできます。 リレーショナル データベース データへのアクセス用の SqlDataSource コントロール、クラスからのデータへのアクセス用の ObjectDataSource コントロールなど、いくつかの組み込みのデータ ソース コントロールが存在します。 独自のカスタム データ ソース コントロールを作成することもできます。

データ ソース コントロールは、ASP.NET ページと基になるデータの間のプロキシとして機能します。 データ ソース コントロールの取得データを表示するためには、通常は別の Web コントロールをページに追加し、それをデータ ソース コントロールにバインドします。 Web コントロールをデータ ソース コントロールにバインドするには、Web コントロールの DataSourceID プロパティをデータ ソース コントロールの ID プロパティの値に設定するだけで済みます。

サイト マップのデータの操作を支援するために、ASP.NET には SiteMapDataSource コントロールが含まれており、これを使用すると Web コントロールを Web サイトのサイト マップにバインドできます。 TreeView と Menu という 2 つの Web コントロールは、ナビゲーション ユーザー インターフェイスを提供するために一般的に使用されます。 サイト マップ データをこれら 2 つのコントロールのいずれかにバインドするには、DataSourceID プロパティが適切に設定されている TreeView または Menu コントロールと共に SiteMapDataSource をページに追加するだけで済みます。 たとえば、次のマークアップを使用して、Menu コントロールをマスター ページに追加できます。

<div id="navigation">
    <asp:Menu ID="Menu1" runat="server"
      DataSourceID="SiteMapDataSource1">
    </asp:Menu>

    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
</div>

出力される HTML をより細かく制御するには、以下のように、SiteMapDataSource コントロールを Repeater コントロールにバインドします。

<div id="navigation">
    <ul>
        <li><asp:HyperLink runat="server" ID="lnkHome"
         NavigateUrl="~/Default.aspx">Home</asp:HyperLink></li>

        <asp:Repeater runat="server" ID="menu"
          DataSourceID="SiteMapDataSource1">
            <ItemTemplate>
                <li>
                    <asp:HyperLink runat="server"
                    NavigateUrl='<%# Eval("Url") %>'>
                    <%# Eval("Title") %></asp:HyperLink>
                </li>
            </ItemTemplate>
        </asp:Repeater>
    </ul>

    <asp:SiteMapDataSource ID="SiteMapDataSource1"
      runat="server" ShowStartingNode="false" />
</div>

この SiteMapDataSource コントロールは、ルート サイト マップ ノード (このサイト マップではホーム) から始まり、続けて次のレベル (Basic Reporting、Filtering Reports、および Customized Formatting) といったように、一度に 1 つのレベルのサイト マップ階層を返します。 SiteMapDataSource を Repeater にバインドすると、これは返された最初のレベルを列挙し、その最初のレベルの SiteMapNode インスタンスごとに ItemTemplate のインスタンスを作成します。 SiteMapNode の特定のプロパティにアクセスするには、Eval(propertyName) を使用します。これが HyperLink コントロールのために各 SiteMapNodeUrl および Title プロパティを取得する方法です。

上記の Repeater の例では、次のマークアップがレンダリングされます。

<li>
    <a href="/Code/BasicReporting/Default.aspx">Basic Reporting</a>
</li>

<li>
    <a href="/Code/Filtering/Default.aspx">Filtering Reports</a>
</li>

<li>
    <a href="/Code/CustomFormatting/Default.aspx">
     Customized Formatting</a>
</li>

これらのサイト マップ ノード (Basic Reporting、Filtering Reports、および Customized Formatting) が構成するのは、レンダリングされるサイト マップの "2 番目" のレベルであり、最初のレベルではありません。 これは、SiteMapDataSource の ShowStartingNode プロパティが False に設定されていることが原因で、SiteMapDataSource がルート サイト マップ ノードをバイパスし、代わりにサイト マップ階層内の 2 番目のレベルから返し始めるからです。

Basic Reporting、Filtering Reports、および Customized Formatting の SiteMapNode の子要素を表示するには、最初の Repeater の ItemTemplate に別の Repeater を追加します。 この 2 番目の Repeater は、以下のように、SiteMapNode インスタンスの ChildNodes プロパティにバインドされます。

<asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">
    <ItemTemplate>
        <li>
            <asp:HyperLink runat="server"
             NavigateUrl='<%# Eval("Url") %>'>
             <%# Eval("Title") %></asp:HyperLink>

            <asp:Repeater runat="server"
                DataSource='<%# ((SiteMapNode) Container.DataItem).ChildNodes %>'>
                <HeaderTemplate>
                    <ul>
                </HeaderTemplate>

                <ItemTemplate>
                    <li>
                        <asp:HyperLink runat="server"
                         NavigateUrl='<%# Eval("Url") %>'>
                         <%# Eval("Title") %></asp:HyperLink>
                    </li>
                </ItemTemplate>

                <FooterTemplate>
                    </ul>
                </FooterTemplate>
            </asp:Repeater>
        </li>
    </ItemTemplate>
</asp:Repeater>

これら 2 つの Repeater の結果は次のマークアップとなります (簡潔にするために一部のマークアップが削除されています)。

<li>
    <a href="/Code/BasicReporting/Default.aspx">Basic Reporting</a>
    <ul>
       <li>
          <a href="/Code/BasicReporting/SimpleDisplay.aspx">
            Simple Display</a>
       </li>
       <li>
          <a href="/Code/BasicReporting/DeclarativeParams.aspx">
            Declarative Parameters</a>
       </li>
       <li>
          <a href="/Code/BasicReporting/ProgrammaticParams.aspx">
            Setting Parameter Values</a>
       </li>
    </ul>
</li>

<li>
    <a href="/Code/Filtering/Default.aspx">Filtering Reports</a>
    ...
</li>

<li>
    <a href="/Code/CustomFormatting/Default.aspx">
      Customized Formatting</a>
    ...
</li>

Rachel Andrew による書籍「CSS Anthology: 101 Essential Tips, Tricks, & Hacks」から選択された CSS スタイルを使用して、マークアップが次のような視覚的出力を生成するように <ul> および <li> 要素のスタイルが設定されています。

A Menu Composed from Two Repeaters and Some CSS

図 11: 2 つの Repeater と CSS から構成されるメニュー

このメニューはマスター ページ内にあり、Web.sitemap 内で定義されているサイト マップにバインドされています。つまり、サイト マップへのすべての変更は、Site.master マスター ページを使用するすべてのページに直ちに反映されます。

ViewState の無効化

すべての ASP.NET コントロールは、必要に応じてその状態をビュー状態に保持できます。これはレンダリングされた HTML 内の非表示フォーム フィールドとしてシリアル化されます。 ビュー状態は、データ Web コントロールにバインドされたデータなど、プログラムによって変更された状態をポストバックをまたいで記憶するためにコントロールによって使用されます。 ビュー状態は、ポストバックをまたいで情報が記憶されることを可能にしますが、クライアントに送信する必要があるマークアップのサイズを大きくするため、厳密に監視しないと深刻なページの肥大化の原因となる可能性があります。 データ Web コントロール、特に GridView は、ページに数十キロバイトのマークアップを追加することで非常に有名です。 このような増加はブロードバンドやイントラネットのユーザーにとっては無視できるものかもしれませんが、ダイヤルアップ ユーザーのラウンド トリップは、ビュー状態が原因で数秒増加する可能性があります。

ビュー状態の影響を確認するには、ブラウザーでページにアクセスして、Web ページによって送信されたソースを表示します (Internet Explorer では、[表示] メニューに移動し、[ソース] オプションを選択します)。 ページ トレースを有効にして、ページ上の各コントロールによって使用されるビュー状態の割り当てを確認することもできます。 ビュー状態の情報は、__VIEWSTATE という名前の非表示のフォーム フィールド内でシリアル化され、これは <form> の開始タグの直後の <div> 要素内にあります。 ビュー状態が保持されるのは、使用されている Web フォームがある場合だけです。ASP.NET ページの宣言構文に <form runat="server"> が含まれていない場合、レンダリングされたマークアップ内に __VIEWSTATE 非表示フォーム フィールドは含まれません。

マスター ページによって生成された __VIEWSTATE フォーム フィールドによって、ページの生成されたマークアップに追加されるのは約 1,800 byte です。 SiteMapDataSource コントロールのコンテンツはビュー状態に保持されるため、この余分な肥大化は主に Repeater コントロールによるものです。 余計な 1,800 byte は気にする程のものではないと思われるかもしれませんが、多くのフィールドとレコードを含む GridView を使用すると、ビュー状態は容易に 10 倍以上に肥大化する可能性があります。

ビュー状態は、EnableViewState プロパティを false に設定することで、ページまたはコントロール レベルで無効にし、その結果として、レンダリングされるマークアップのサイズを小さくできます。 データ Web コントロールのビュー状態は、そのデータ Web コントロールにバインドされたデータをポストバックをまたいで保持するため、データ Web コントロールのビュー状態を無効にする場合は、データを各ポストバックで毎度バインドする必要があります。 ASP.NET バージョン 1.x では、この責任はページ開発者にありました。しかし、ASP.NET 2.0 では、データ Web コントロールが必要に応じて各ポストバックでデータ ソース コントロールへの再バインドを行います。

ページのビュー状態を減らすには、Repeater コントロールの EnableViewState プロパティを false に設定しましょう。 これは、Designer のプロパティ ウィンドウを通して、またはソース ビューで宣言的に実行できます。 この変更を行った後の Repeater の宣言型マークアップは次のようになるはずです。

<asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1"
    EnableViewState="False">
    <ItemTemplate>
        ... <i>ItemTemplate contents omitted for brevity</i> ...
    </ItemTemplate>
</asp:Repeater>

この変更後、ページのレンダリングされたビュー状態サイズはわずか 52 byte にまで縮小し、ビュー状態サイズの 97% の節約を達成できました。 このシリーズのチュートリアルを通して、レンダリングされるマークアップのサイズを小さくするために、データ Web コントロールのビュー状態は既定で無効にします。 ほとんどの例では、EnableViewState プロパティは false に設定され、これは言及なく実行されます。 ビュー状態に関して言及があるのは、データ Web コントロールが期待される機能を提供するためにビュー状態を有効にする必要があるシナリオにおいてだけです。

手順 4: 階層リンク ナビゲーションの追加

マスター ページを完成させるために、各ページに階層リンク ナビゲーション UI 要素を追加しましょう。 階層リンクは、ユーザーに対してサイト階層内のユーザーの現在の位置をすばやく表示します。 ASP.NET 2.0 での階層リンクの追加は、SiteMapPath コントロールをページに追加するだけという簡単なもので、コードは必要ありません。

このサイトでは、以下のように、このコントロールをヘッダー <div> に追加します。

<span class="breadcrumb">
    <asp:SiteMapPath ID="SiteMapPath1" runat="server">
    </asp:SiteMapPath>
</span>

階層リンクは、ユーザーがアクセスしているサイト マップ階層内の現在のページと、そのサイト マップ ノードの "先祖" をルート (このサイト マップではホーム) まですべて表示します。

The Breadcrumb Displays the Current Page and its Ancestors in the Site Map Hierarchy

図 12: 階層リンクは、現在のページとそのサイト マップ階層内の先祖を表示します

手順 5: 各セクションの既定のページの追加

このサイトのチュートリアルは、Basic Reporting、Filtering、Custom Formatting などのさまざまなカテゴリに分類され、各カテゴリのフォルダーと、そのフォルダー内の ASP.NET ページとしての対応チュートリアルが付属しています。 さらに、各フォルダーには Default.aspx ページが含まれています。 この既定のページでは、現在のセクションのすべてのチュートリアルを表示しましょう。 つまり、BasicReporting フォルダー内の Default.aspx に対して、SimpleDisplay.aspxDeclarativeParams.aspxProgrammaticParams.aspx へのリンクを設定することになります。 ここでも、SiteMap クラスとデータ Web コントロールを使用して、Web.sitemap 内で定義されているサイト マップに基づいてこの情報を表示できます。

Repeater を再度使用して順序付けされていないリストを表示してみましょう。しかし、今回はチュートリアルのタイトルと説明を表示します。 これを実現するためのマークアップとコードは各 Default.aspx ページに対して反復させる必要があるため、この UI ロジックはユーザー コントロール内にカプセル化できます。 Web サイト内に UserControls という名前のフォルダーを作成し、それに対して SectionLevelTutorialListing.ascx という名前の Web ユーザー コントロール型の新しい項目を追加し、次のマークアップを追加します。

Add a New Web User Control to the UserControls Folder

図 13: UserControls フォルダーに対して新しい Web ユーザー コントロールを追加する (フルサイズ画像を表示するにはこちらをクリックしてください)

SectionLevelTutorialListing.ascx

<%@ Control Language="CS" AutoEventWireup="true"
    CodeFile="SectionLevelTutorialListing.ascx.cs"
    Inherits="UserControls_SectionLevelTutorialListing" %>
<asp:Repeater ID="TutorialList" runat="server" EnableViewState="False">
    <HeaderTemplate><ul></HeaderTemplate>
    <ItemTemplate>
        <li><asp:HyperLink runat="server"
         NavigateUrl='<%# Eval("Url") %>'
         Text='<%# Eval("Title") %>'></asp:HyperLink>
                - <%# Eval("Description") %></li>
    </ItemTemplate>
    <FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

SectionLevelTutorialListing.ascx.cs

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;

public partial class UserControls_SectionLevelTutorialListing : UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // If SiteMap.CurrentNode is not null,
        // bind CurrentNode ChildNodes to the GridView
        if (SiteMap.CurrentNode != null)
        {
            TutorialList.DataSource = SiteMap.CurrentNode.ChildNodes;
            TutorialList.DataBind();
        }
    }
}

先ほどの Repeater の例では、SiteMap データを宣言によって Repeater にバインドしました。しかし、SectionLevelTutorialListing ユーザー コントロールはそれをプログラムによって実行します。 Page_Load イベント ハンドラーでは、このページの URL がサイト マップ内のノードにマップされていることを確認するチェックが行われます。 このユーザー コントロールが、対応する <siteMapNode> エントリを持たないページで使用されている場合、SiteMap.CurrentNodenull を返し、Repeater にはどのようなデータもバインドされません。 CurrentNode を持っていることを仮定して、その ChildNodes コレクションを Repeater にバインドします。 このサイト マップは、各セクションの Default.aspx ページがそのセクション内のすべてのチュートリアルの親ノードになるように設定されているため、このコードは、以下のスクリーンショットに示すように、セクションのすべてのチュートリアルへのリンクとその説明を表示します。

この Repeater が作成されたら、各フォルダーの Default.aspx ページを開き、デザイン ビューに移動し、ソリューション エクスプローラーからチュートリアル リストを表示させたいデザイン画面にユーザー コントロールをドラッグするだけで済みます。

The User Control has Been Added to Default.aspx

図 14: ユーザー コントロールが Default.aspx に追加されました (フルサイズ画像を表示するにはこちらをクリックしてください)

The Basic Reporting Tutorials are Listed

図 15: Basic Reporting チュートリアルが一覧表示されます (フルサイズ画像を表示するにはこちらをクリックしてください)

まとめ

サイト マップが定義され、マスター ページが完成したので、データ関連のチュートリアルに関する一貫したページ レイアウトとナビゲーション スキームが設定できました。 サイトに何個のページを追加しても、サイト全体のページ レイアウトやサイト ナビゲーション情報の更新は、この情報が一元化されているおかげで、迅速かつ単純なプロセスになります。 具体的には、このページ レイアウト情報はマスター ページ Site.masterWeb.sitemap 内のサイト マップで定義されます。 このサイト全体のページ レイアウトとナビゲーション メカニズムを実現するためにコードを記述する必要は "一切" ありませんでした。また、Visual Studio では WYSIWYG デザイナーの完全なサポートを保持しています。

データ アクセス層とビジネス ロジック層を完成させ、一貫したページ レイアウトとサイト ナビゲーションを定義したので、一般的なレポート パターンの確認を開始する準備ができました。 の 3 つのチュートリアルでは、GridView、DetailsView、および FormView コントロールの BLL から取得したデータを表示する基本的なレポート タスクについて確認します。

プログラミングに満足!

もっと読む

この記事で説明したトピックの詳細については、次のリソースを参照してください。

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Liz Shulok、Dennis Patterson、Hilton Giesenow でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。