1

リストビューで次のことを行うことは可能ですか? そうでない場合。私を修正してください。

    <asp:ListView runat="server" ID="lsit">
    <LayoutTemplate>
        <div id="banner">
            <div id="paginate-slider2" class="banner_nav">
                <asp:PlaceHolder runat="server" ID="itemPlaceHolder1" />
            </div>
            <div id="slider2">
                <asp:PlaceHolder runat="server" ID="itemPlaceHolder2" />
            </div>
            <script src="/scripts/banner.js" type="text/javascript"></script>
        </div>
        <div class="clear"></div>
    </LayoutTemplate>
    <ItemTemplate>
        <a href="#" class="toc">
            <img src="./images/gallery/thumbnails/thumb1.gif" alt="" />
        </a> 
    </ItemTemplate>
    <ItemTemplate>
        <div class="contentdiv banner_sec">
            <div class="con_img">
                <img src="./images/gallery/images/img1.gif" alt="" />
            </div>
            <div class="con_desc">
                <h3>Featured</h3>
                <h5>Lorem ipsum dolor sit amet</h5>
                <p>
                    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed elit.
                </p>
                <br />
                <a href="./detail.html" class="buttontwo"><span>Read More</span></a>
            </div>
        </div>
    </ItemTemplate>
</asp:ListView>

更新:このようなものを出力したい。

<!-- Home Banner Section -->
<div id="banner">
    <div id="paginate-slider2" class="banner_nav">
        <!-- this should be repeated for each item -->

        <a href="#" class="toc">
            <img src="./images/gallery/thumbnails/thumb1.gif" alt="" />
        </a> 
    </div>
    <div id="slider2">
        <!-- this should be repeated for each item -->
        <div class="contentdiv banner_sec">
            <div class="con_img">
                <img src="./images/gallery/images/img1.gif" alt="" />
            </div>
            <div class="con_desc">
                <h3>Featured</h3>
                <h5>Lorem ipsum dolor sit amet</h5>
                <p>
                    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed elit. Nulla sem risus, vestibulum in, volutpat eget, dapibus ac, lectus. Curabitur dolor sapien, hendrerit non, suscipit bibendum, auctor ac, arcu. Vestibulum dapibus. Sed pede lacus, pretium in, condimentum sit amet, mollis dapibus, magna. Ut bibendum dolor nec augue. Ut tempus luctus metus. Sed a velit. Pellentesque at libero elementum ante condimentum sollicitudin. Pellentesque lorem ipsum, semper quis, interdum et, sollicitudin eu, purus. Vivamus fringilla ipsum vel orci.
                </p>
                <br />
                <a href="./detail.html" class="buttontwo"><span>Read More</span></a>
            </div>
        </div>
    </div>
    <script src="/scripts/banner.js" type="text/javascript"></script>
</div>
<div class="clear"></div>
4

1 に答える 1

5

asp:ListViewで2つのアイテムテンプレートを定義することは可能ですか?

はい、可能です。 この投稿を読んでください(コードが適切にフォーマットされたらここにコードを投稿するので、紛失しないようにしてください)。

クレジット:

Dino Esposito は IDesign アーキテクトであり、プログラミング ASP.NET 3.5 コア リファレンスの著者です。イタリアを拠点とする Dino は、世界中の業界イベントで頻繁に講演を行っています。彼に連絡するには、cutting@microsoft.com で連絡を取るか、 weblogs.asp.net /desposで彼のブログに参加してください。

複数のアイテム テンプレート

ListView コントロールは、データ ソースをループして次のアルゴリズムを適用することで、マークアップを生成します。最初に、項目セパレーターが必要かどうかをチェックします。その場合、テンプレートをインスタンス化し、データ項目オブジェクトを作成します。データ アイテム オブジェクトは、アイテム テンプレートのコンテナーであり、ビュー内のアイテムのインデックスとバインドされたデータ ソースに関する情報を保持します。アイテム テンプレートがインスタンス化されると、ItemCreated イベントが発生します。次のステップはデータバインディングです。これが完了すると、ItemDataBound イベントが発生します。

ご覧のとおり、各アイテムのテンプレートをプログラムで変更できる、処理できるパブリック イベントはありません。Init または Load ページ イベントでテンプレートを変更できますが、それはバインドされたすべてのアイテムに適用されます。ItemCreated を処理し、そこで ItemTemplate プロパティを設定すると、変更は次のアイテムに影響しますが、現在処理中のアイテムには影響しません。ItemCreating イベントが必要ですが、そのようなイベントは ListView コントロールによって発生しません。解決策は、図 6 に示すように、独自の ListView コントロールを作成することです。

図 6 ItemCreating イベントの発生

namespace Samples.Controls
{
  public class ListViewItemCreatingEventArgs : EventArgs
  {
    private int _dataItemIndex;
    private int _displayIndex;

    public ListViewItemCreatingEventArgs(int dataItemIndex,
                                         int displayIndex) {
      _dataItemIndex = dataItemIndex;
      _displayIndex = displayIndex;
    }

    public int DisplayIndex {
      get { return _displayIndex; }
      set { _displayIndex = value; }
    }

    public int DataItemIndex {
      get { return _dataItemIndex; }
      set { _dataItemIndex = value; }
    }
  }

  public class ListView : System.Web.UI.WebControls.ListView
  {
    public event EventHandler<ListViewItemCreatingEventArgs>
                                               ItemCreating;

    protected override ListViewDataItem CreateDataItem(int
                           dataItemIndex, int displayIndex) {
      // Fire a NEW event: ItemCreating
      if (ItemCreating != null)
        ItemCreating(this, new ListViewItemCreatingEventArgs
                             (dataItemIndex, displayIndex));

      // Call the base method
      return base.CreateDataItem(_dataItemIndex, displayIndex);
    }
  }
}

CreateDataItem メソッドをオーバーライドすることで、項目テンプレートがインスタンス化される直前にコードを実行できる可能性があります。CreateDataItem メソッドは、ListView クラスで保護および仮想として宣言されています。図 6 からわかるように、メソッドのオーバーライドは非常に単純です。最初にカスタム ItemCreating イベントを発生させてから、基本メソッドを呼び出して続行します。

ItemCreating イベントは、いくつかの整数 (データ ソース内のアイテムの絶対インデックスとページ固有のインデックス) をユーザー コードに返します。たとえば、ページ サイズが 10 の場合、ListView が 2 番目のページの最初のアイテムのレンダリングに取り組んでいる場合、dataItemIndex には 11 個のアイテムが含まれ、displayIndex には 1 個のアイテムが含まれます。新しい ItemCreating イベントを使用するには、次のコードでわかるように、カスタム ListView コントロールでメソッドとハンドラーを宣言するだけです。

<x:ListView runat="server" ID="ListView1" 
   ItemPlaceholderID="itemPlaceholder"
   DataSourceID="ObjectDataSource1"
   OnItemCreating="ListView1_ItemCreating">
   <LayoutTemplate>
      <div>
         <asp:PlaceHolder runat="server" ID="itemPlaceholder" /> 
      </div>
   </LayoutTemplate>
</x:ListView>

コードでは、次のようにイベントを処理できます。

void ListView1_ItemCreating(
     object sender, ListViewItemCreatingEventArgs e)
{
    string url = "standard.ascx";
    if (e.DisplayIndex % DataPager1.PageSize == 0)
        url = "firstItem.ascx";

    ListView1.ItemTemplate = Page.LoadTemplate(url);
}

ここでは、2 つの異なるユーザー コントロールを使用して、データ項目をレンダリングします。特定のユーザー コントロールは、表示インデックスによって決定されます。最初の項目を除いて、すべての項目が同じテンプレートを共有します。図 7 は、動作中のページを示しています。

一般的な現実世界のページの複雑さを考えると、このソリューションは単純すぎるように見えます。多くの場合、表示するコンテンツに基づいて異なるテンプレートを使用する必要があります。カスタム ListView コントロールをさらに拡張して、データ バインディング プロセス内で項目テンプレートを変更する必要があります。図 8 のコードを見てください。

図 8 コンテンツに基づくテンプレートの選択

namespace Samples.Controls
{
  public class ListViewItemCreatingEventArgs : EventArgs
  {
    private int _dataItemIndex;
    private int _displayIndex;

    public ListViewItemCreatingEventArgs(int dataItemIndex,
                                         int displayIndex) {
      _dataItemIndex = dataItemIndex;
      _displayIndex = displayIndex;
    }

    public int DisplayIndex {
      get { return _displayIndex; }
      set { _displayIndex = value; }
    }

    public int DataItemIndex {
      get { return _dataItemIndex; }
      set { _dataItemIndex = value; }
    }
  }

  public class ListView : System.Web.UI.WebControls.ListView
  {
    public event EventHandler<ListViewItemCreatingEventArgs>
     ItemCreating;

    private int _displayIndex;
    private bool _shouldInstantiate = false;

    protected override void InstantiateItemTemplate(Control container,
     int displayIndex) {
      if (_shouldInstantiate) {
        base.InstantiateItemTemplate(container, displayIndex);
        _shouldInstantiate = false;
      }
    }

    protected override ListViewDataItem CreateDataItem(int
     dataItemIndex, int displayIndex) {
      // Fire a NEW event: ItemCreating
      if (ItemCreating != null)
        ItemCreating(this, new
          ListViewItemCreatingEventArgs(dataItemIndex,
          displayIndex));

      // Cache for later
      _displayIndex = displayIndex;

      // Call the base method
      return base.CreateDataItem(_dataItemIndex, displayIndex);
    }

    protected override void OnItemCreated(ListViewItemEventArgs e) {
      base.OnItemCreated(e);

      // You can proceed with template instantiation now
      _shouldInstantiate = true;
      InstantiateItemTemplate(e.Item, _displayIndex);
    }
  }
}

CreateDataItem メソッドは、ItemCreating イベントを発生させ、後で使用するために表示インデックスをキャッシュします。さらに、InstantiateItemTemplate メソッドをオーバーライドして、実際のテンプレートのインスタンス化を遅らせます。そのために、プライベート ブール フラグが使用されます。前述のように、ListView は項目テンプレートをインスタンス化した後にデータ バインディング プロセスを開始します。

ただし、図 8 のコードに示されている実装では、ItemCreated イベントが発生するまでアイテム テンプレートは実際にはインスタンス化されません。ItemCreated イベントが発生すると、データ項目オブジェクトは DataItem プロパティを通じて ListView 項目コンテナーにバインドされます。コードで ItemCreated イベントを処理することにより、次のように、バインドされたデータ項目に基づいて使用する項目テンプレートを決定できます。

protected override void OnItemCreated(ListViewItemEventArgs e)
{
   base.OnItemCreated(e);

   _shouldInstantiate = true;
   InstantiateItemTemplate(e.Item, _displayIndex);
}

この場合、ベース メソッドは ItemCreated イベントをページに対して発生させます。その後、カスタム ListView コントロールは Boolean フラグをリセットし、メソッドを呼び出して項目テンプレートをインスタンス化します。最終的に、項目テンプレートは組み込みの ListView コントロールよりも少し遅れてインスタンス化されますが、バインドされたデータ項目の内容を確認した後、ItemCreated イベント ハンドラーでプログラムによって各項目の ItemTemplate プロパティを設定できます (図を参照)。 9)。図 10 は、男性用に青色のテンプレートが使用され、女性用にピンク色のテンプレートが使用されているサンプル ページを示しています。

図 9 アイテム テンプレートの設定

void ListView1_ItemCreated(object sender, ListViewItemEventArgs e)
{
    // Grab a reference to the data item
    ListViewDataItem currentItem = (e.Item as ListViewDataItem);
    Employee emp = (Employee) currentItem.DataItem;
    if (emp == null)
        return;

    // Apply your logic here
    string titleOfCourtesy = emp.TitleOfCourtesy.ToLower();
    string url = "forgentlemen.ascx";
    if (titleOfCourtesy == "ms." || titleOfCourtesy == "mrs.")
        url = "forladies.ascx";

    // Set the item template to use
    Samples.ListView ctl = (sender as Samples.Controls.ListView);
    ctl.ItemTemplate = Page.LoadTemplate(url);
}
于 2012-07-15T15:04:36.340 に答える