是否可以在asp:ListView中定义两个项目模板? [英] Is it possible to define two item template in asp:ListView?

查看:47
本文介绍了是否可以在asp:ListView中定义两个项目模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在列表视图中执行以下操作?如果不.请纠正我.

Is it possible to do the following in listview? if not. please correct me.

    <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>

更新:我想输出这样的东西;

Update: I want to output something like this;

<!-- 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>

推荐答案

是否可以在asp:ListView中定义两个项目模板?

Is it possible to define two item template in asp:ListView?

是的,有可能.阅读本文(我将在此处发布代码将其正确格式化,以免丢失).

Yes, it's possible. Read this post (I'll post the code here when I get it formatted properly, so it doesn't get lost).

积分:

Dino Esposito是IDesign架构师,并且是《 ASP.NET 3.5核心编程》的作者.Dino总部位于意大利,经常在世界各地的行业活动中演讲.您可以通过 cutting@microsoft.com 与他联系,也可以通过weblogs.asp.net/despos加入他的博客.

Dino Esposito is an IDesign architect and the author of Programming ASP.NET 3.5 Core Reference. Based in Italy, Dino is a frequent speaker at industry events worldwide. You can reach him at cutting@microsoft.com or join his blog at weblogs.asp.net/despos.

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

The ListView control generates its markup by looping through the data source and applying the following algorithm. First, it checks whether an item separator is required. If so, it instantiates the template and creates the data item object. The data item object is the container of the item template and carries information about the index of the item in the view and the bound data source. When the item template is instantiated, the ItemCreated event fires. The next step is data binding. After this has completed, the ItemDataBound event is fired.

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

As you can see, there's no public event that you can handle that allows programmatically changing the template for each item. You can change the template in the Init or Load page event, but that would be for all bound items. If you handle ItemCreated and set the ItemTemplate property there, the change will affect the next item, but not the item being currently processed. You would need an ItemCreating event, but no such an event is fired by the ListView control. The solution, then, is to create your own ListView control, as in Figure 6.

图6触发ItemCreating事件

Figure 6 Firing an ItemCreating Event

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方法,可以在实例化项目模板之前运行代码.在ListView类中,CreateDataItem方法被声明为受保护且是虚拟的.正如您在图6中看到的那样,方法重写非常简单.您首先触发一个自定义ItemCreating事件,然后通过调用基本方法进行操作.

By overriding the CreateDataItem method, you have a chance to run your code just before the item template is instantiated. The CreateDataItem method is declared protected and virtual in the ListView class. As you can see in Figure 6, the method override is quite simple. You first fire a custom ItemCreating event and then proceed by calling the base method.

ItemCreating事件将几个整数传递回用户代码-数据源中项目的绝对索引和特定于页面的索引.例如,对于页面大小为10的列表视图在渲染第二个页面的第一项时,dataItemIndex包含11个项目,而displayIndex包含1个项目.为了使用新的ItemCreating事件,只需在自定义ListView控件上声明方法和处理程序,如下面的代码所示:

The ItemCreating event passes a couple of integers back to the user code—the absolute index of the item in the data source and the page-specific index. For example, for a page size of 10, when the ListView is working on rendering the first item of the second page, dataItemIndex contains 11 items and displayIndex contains 1 item. In order to use the new ItemCreating event, simply declare the method and handler on your custom ListView control, as you can see in the following code:

<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>

在您的代码中,您可以像这样处理事件:

In your code, you can handle the event like so:

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显示了正在运行的页面.

Here, two different user controls are employed to render the data items. The specific user control is determined by the display index. All items share the same template except the first. Figure 7 shows the page in action.

当您考虑现实世界中常见页面的复杂性时,此解决方案似乎太简单了.通常,您需要根据要显示的内容使用不同的模板.您需要进一步增强自定义ListView控件,以在数据绑定过程中更改项目模板.看一下图8中的代码.

When you think about the complexity of common real-world pages, this solution appears too simple. More often than not, you need to use different templates based on the content to display. You need to further enhance the custom ListView control to change the item template within the data-binding process. Have a look at the code in Figure 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在实例化项目模板后开始数据绑定过程.

The CreateDataItem method fires the ItemCreating event and caches the display index for later use. In addition, the InstantiateItemTemplate method is overridden to delay the actual template instantiation. A private boolean flag is used for that purpose. As mentioned, the ListView starts the data-binding process after instantiating the item template.

然而,在图8中的代码所示的实现中,在激发ItemCreated事件之前,没有真正实例化任何项模板.引发ItemCreated事件时,数据项对象通过DataItem属性绑定到ListView项容器.通过处理代码中的ItemCreated事件,您可以根据绑定的数据项决定要使用的项目模板,如下所示:

In the implementation shown in the code in Figure 8, however, no item template is really instantiated until the ItemCreated event is fired. When the ItemCreated event is raised, the data item object is bound to the ListView item container through the DataItem property. By handling the ItemCreated event in your code, you can decide which item template to use based on the bound data item, as you can see here:

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

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

在这种情况下,基本方法将ItemCreated事件触发到页面.之后,自定义ListView控件将重置Boolean标志,并调用该方法以实例化项目模板.最后,在内置ListView控件中实例化项目模板要晚一些,但是在查看绑定数据项的内容之后,可以在ItemCreated事件处理程序中以编程方式为每个项目设置ItemTemplate属性(请参见图5).9).图10显示了一个示例页面,其中男性使用蓝色模板,女性使用粉红色模板.

In this case, the base method fires the ItemCreated event to the page. After that, the custom ListView control resets the Boolean flag and invokes the method to instantiate the item template. In the end, the item template is instantiated a bit later than in the built-in ListView control, but you can set the ItemTemplate property for each item programmatically in the ItemCreated event handler after looking at the content of the bound data item (see Figure 9). Figure 10 shows a sample page where a blue template is used for men and a pink template is used for women.

图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);
}

这篇关于是否可以在asp:ListView中定义两个项目模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆