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 中定义两个项目模板?

是的,这是可能的。 阅读这篇文章(当我正确格式化代码后,我会在此处发布代码,以免丢失)。

学分:

Dino Esposito 是一名 IDesign 架构师,也是 Programming ASP.NET 3.5 Core Reference 的作者。Dino 常驻意大利,经常在全球行业活动中发表演讲。您可以通过cutting@microsoft.com 与他联系,或通过weblogs.asp.net/despos加入他的博客。

多个项目模板

ListView 控件通过循环遍历数据源并应用以下算法来生成其标记。首先,它检查是否需要项目分隔符。如果是这样,它会实例化模板并创建数据项对象。数据项对象是项模板的容器,携带了项在视图中的索引和绑定的数据源的信息。实例化项目模板时,会触发 ItemCreated 事件。下一步是数据绑定。完成后,将触发 ItemDataBound 事件。

如您所见,没有可以处理的公共事件允许以编程方式更改每个项目的模板。您可以在 Init 或 Load 页面事件中更改模板,但这适用于所有绑定项目。如果您处理 ItemCreated 并在那里设置 ItemTemplate 属性,则更改将影响下一个项目,但不会影响当前正在处理的项目。您将需要一个 ItemCreating 事件,但 ListView 控件不会触发此类事件。然后,解决方案是创建您自己的 ListView 控件,如图 6 所示。

图 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 正在渲染第二页的第一项时,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);
}

在这里,使用两个不同的用户控件来呈现数据项。具体的用户控件由显示索引决定。除了第一个项目外,所有项目都共享相同的模板。图 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 控件重置布尔标志并调用方法来实例化项模板。最后,项目模板的实例化时间比内置 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 回答