weblao

随 Visual Studio® 2008 一同发布的 ASP.NET 3.5 引入了新的数据绑定控件—ListView。我知道您正在想什么:为什么 ASP.NET 里还需要另一个数据绑定控件呢?毕竟,当显示数据收集时,我们已经有超过 10 个控件可供选择,其中包括逐渐不再使用的 DataGrid、新的和改进的 GridView、非常可靠和简单的 Repeater、独特和灵活的 DataList、方便的 FormView 及其稍显冗余的同行 DetailsView。当然,还有一维列表控件 BulletedList、ListBox、DropDownList、RadioButtonList 和 CheckBoxList。
理论上,ListView 可以取代 ASP.NET 里的所有其它数据绑定控件。这一点没有疑义。您可以使用 ListView 控件代替上面列表中的其他每个控件。ListView 还可以使一些数据绑定任务比使用前几个控件工作起来更加便利,包括 CSS 样式设定、灵活的分页和完善的排序、插入、删除和更新功能。
我们让介绍 ListView 的典型使用模式,然后讲解控件的功能,展示其灵活性和强大的能力。在本专栏的结尾,您将掌握足够的信息来决定应该在您的 ASP.NET 工具箱中保留多少个数据绑定控件。
 
ListView 基础
ListView 是模板驱动的控件,这意味着它默认情况下不会呈现任何数据——您必须以模板的形式完全指定希望它呈现的 HTML。与大多数模板控件类似,ItemTemplate 将成为您工作的重点,您需要将绑定数据集中每一行不断重复的 HTML 内容放在 ItemTemplate 里。
ListView 中的新功能,也是它与其它控件的真正不同之处在于引进了 LayoutTemplate。在 LayoutTemplate 中,您可以将要输出的顶级 HTML 定义为控件呈现的内容。例如,如果希望 ListView 作为表格呈现,则可以在 LayoutTemplate 中包含顶级 <table> 和 <thead> 元素,把行和单元格的呈现留给 ItemTemplate,如图 1 所示(在本示例中,绑定的数据源将显示包含电影标题和发行日期的简单表格)。图 2 显示了浏览器呈现。
  Figure 1 Using LayoutTemplate and ItemTemplate
  复制代码
<asp:ListView runat="server" ID="_simpleTableListView"
  DataSourceID="_moviesDataSource">
  <LayoutTemplate>
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>Title</th>
          <th>Release Date</th>
        </tr>
      </thead>
      <tbody>
        <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
      </tbody>
    </table>
  </LayoutTemplate>
  <ItemTemplate>
    <tr>
      <td><%# Eval("movie_id") %></td>
      <td><%# Eval("title") %></td>
      <td><%# Eval("release_date", "{0:d}") %></td>
    </tr>
  </ItemTemplate>
</asp:ListView>
 
Figure 2 显示在表格中的列表 (单击该图像获得较大视图)
LayoutTemplate 和 ItemTemplate 之间的关联由 LayoutTemplate 中 ID 设置为 itemPlaceholder 的单一服务器端控件完成。(您可以使用 ListView 的 ItemPlaceholderID 属性更改 ID 字符串的默认值。)在第一个示例中,我将 PlaceHolder 控件的实例放置在模板中,即我希望注入 ItemTemplate 内容的位置。请注意:尽管必须支持子控件,但并没有限制必须使用什么类型的控件作为占位符——ID 才是重要。例如,我可以使用服务器端表格行代替 PlaceHolder 控件编写 LayoutTemplate,实现同样的效果:
  复制代码
<LayoutTemplate>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>Title</th>
        <th>Release Date</th>
      </tr>
    </thead>
    <tbody>
      <tr runat="server" ID="itemPlaceholder" />
    </tbody>
  </table>
</LayoutTemplate>
通常情况下,出于以下两个原因,我更喜欢使用通用的 PlaceHolder 控件。第一个原因是名称匹配得很好。而且,该控件并不呈现其自身的 HTML,而是用 ItemTemplate 的内容代替,因此如果控件除在层次结构中保留位置以外无任何其它目的,这是更合乎逻辑的选择。
当然,使 ListView 如此灵活的原因是您可以完全控制 LayoutTemplate 的内容。您不是只能使用表格——您可以将任何希望呈现的 HTML 放置在 LayoutTemplate 中,只要注入 itemPlaceholder 控件位置时 ItemTemplate 的内容有效即可。以下是绑定到相同电影数据源的 ListView 示例,但这次不是表格,是带有标题和发行日期的电影显示在项目符号列表中(结果列表如图 3 所示):
 
Figure 3 相同列表,不同格式 (单击该图像获得较大视图)
  复制代码
   <asp:ListView runat="server"
     ID="_simpleTableListView"
     DataSourceID="_moviesDataSource">
     <LayoutTemplate>
       <ul>
         <asp:PlaceHolder runat="server"
              ID="itemPlaceholder" />
       </ul>
     </LayoutTemplate>
     <ItemTemplate>
       <li><%# Eval("title") %>,
           <%# Eval("release_date", "{0:d}") %> </li>
     </ItemTemplate>
                         </asp:ListView>
 
ListView 和 CSS
ASP.NET 开发人员长久以来在创建 CSS 驱动的站点时都受到单独控件的限制。许多默认控件呈现内联样式,或者难于使 CSS 类与其 HTML 输出部分相关联。实际上 Microsoft 在 2006 年 4 月已发布名为“CSS 控件适配器”的工具包,该工具包为几个完全由 CSS 驱动的控件(包括 GridView)提供了可选呈现机制,帮助纠正该问题(有关详细信息,请参见 2006 年 10 月的“非常 ASP.NET”专栏msdn.microsoft.com/msdnmag/issues/06/10/ExtremeASPNET)。这些备用呈现机制从未并入完整版当中,所以需要单独安装且缺少设计人员支持。
ListView 通过让您完全控制何时何地应用样式表,使您在站点里利用 CSS 变得更为简捷。一种常见的情形是开发人员为特定页面手动预先设计,通常包含 HTML 和 CSS。采用传统的 GridView 呈现数据表的特定设计总是很难保证正确,因为 GridView 类仅提供用于修改 HTML 结果的有限挂接集。
我见过许多开发人员经历过的试验和错误,将样式属性应用到网格,查看页面源以准确理解样式放置的位置,并反复试验直到网格能够按要求呈现为止。使用 ListView,您不必再做这些猜测工作了,因为现在您可以控制布局和内容。
例如,假设提供给您的表格需要按照图 4 所示的方式显示,并使用由 .htm 和 .css 文件组成的设计,如图 5中所示。
  Figure 5 HTML and CSS for the Table


HTML
  复制代码
<div class="PrettyGrid">
  <table cellpadding="0" cellspacing="0" summary="">
    <thead>
      <tr>
        <th scope="col"><a href="http://.">ID</a></th>
        <th scope="col"><a href="http://.">Title</a></th>
        <th scope="col"><a href="http://.">Release date</a></th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>Where the Wild Things Are</td>
        <td>12/15/2008</td>
      </tr>
  <!-- ... -->
    </tbody>
  </table>
  <div class="Pagination">
    <span>1</span>
    <a href="http://.">2</a>
    <a href="http://.">3</a>
  </div>
</div>
CSS
  复制代码
.PrettyGrid
{
  width: 100%;
}

.PrettyGrid div.Pagination,
.PrettyGrid div.Pagination a,
.PrettyGrid div.Pagination span
{
  color: #00FFFF;
  background: #284775;
  font-weight: normal;
  padding: 2px;
}
.PrettyGrid table
{
  border: solid 1px #CCCCCC;
  width: 100%;
}
/*...*/
 
Figure 4 表格目标设计 (单击该图像获得较大视图)
您可以通过从 HTML 中选取适当部分,并将其置于的对应模板中,来快速创建能够精确按照 HTML/CSS 组合要求呈现的 ListView,如图 6 所示。最终结果将与完全使用 CSS 设定 HTML 样式时完全一致。仅更新 HTML 或相应的 CSS 就可以很容易地修改设计。
  Figure 6 ListView to Construct the Table
  复制代码
<asp:ListView ID="_moviesGrid" runat="server" DataKeyNames="movie_id"
  DataSourceID="_moviesDataSource">            
  <LayoutTemplate>
    <div class="PrettyGrid">
      <table cellpadding="0" cellspacing="0" summary="">
        <thead>
          <tr>
            <th scope="col"><a href="http://.">ID</a ></th>
            <th scope="col"><a href="http://.">Title</a></th>
            <th scope="col"><a href="http://.">Release date</a></th>
          </tr>
        </thead>
        <tbody>
          <asp:PlaceHolder ID="itemPlaceholder" runat="server" />  
        </tbody>
      </table>
      <div class="Pagination">
        <span>1</span>
        <a href="http://.">2</a>
        <a href="http://.">3</a>
      </div>
    </div>
  </LayoutTemplate>

  <AlternatingItemTemplate>
    <tr class="Alternate">
      <td><asp:Label ID="movie_idLabel" runat="server"
        Text=\'<%# Eval("movie_id") %>\' /></td>
      <td><asp:Label ID="titleLabel" runat="server"
        Text=\'<%# Eval("title") %>\' /></td>
      <td><asp:Label ID="release_dateLabel" runat="server"
        Text=\'<%# Eval("release_date", "{0:d}") %>\' />  </td>
    </tr>
  </AlternatingItemTemplate>  

  <ItemTemplate>
    <tr>
      <td><asp:Label ID="movie_idLabel" runat="server"
        Text=\'<%# Eval("movie_id") %>\' /></td>
      <td><asp:Label ID="titleLabel" runat="server"
        Text=\'<%# Eval("title") %>\' /></td>
      <td><asp:Label ID="release_dateLabel" runat="server"
        Text=\'<%# Eval("release_date", "{0:d}") %>\' /> </td>
    </tr>
  </ItemTemplate>
</asp:ListView>
 
分页
在前一部分开始时介绍的原 HTML 设计中内含分页和排序,所以根据规范完整实现该网格的任务尚未完成。我们先分页,然后再排序。
ListView 控件中的分页通过引入另一个新控件 DataPager 实现。通过在单独的控件中隔离分页,DataPager 将分页 UI 与 ListView 用于呈现数据的页面分离。这意味着您可以在页面的任何位置放置分页 UI,并且可以创建任意多个 DataPager 控件。分页控件一个常见的应用是在数据网格的顶部和底部提供分页界面,这样用户不必滚动网格即可导航到下一页——DataPager 可以很容易做到这一点。
我们先在上一节的 ListView 示例中实现分页。要创建与 ListView 关联的 DataPager 控件,最简单方法是将 DataPager 控件实际嵌入到 ListView 的 LayoutTemplate 中:
  复制代码
<asp:ListView ID="_moviesGrid"
  runat="server" DataKeyNames="movie_id"
  DataSourceID="_moviesDataSource">            
  <LayoutTemplate>
    <!-- ... -->
    <div class="Pagination">
      <asp:DataPager ID="_moviesGridDataPager" runat="server">
        <Fields>
          <asp:NumericPagerField />
        </Fields>
      </asp:DataPager>
    </div>
  </LayoutTemplate>
</asp:ListView>
通过将 DataPager 嵌入 ListView 的 LayoutTemplate 中,它们会建立内在联系。另一种方法是将 DataPager 放在页面的其它位置,并通过将其 PagedControlID 设置为关联 ListView 的 ID 以便与 ListView 关联。
在这种特例中,NumericPagerField 精确显示了我想要的界面——就是一系列显示为超链接的数字,可以导航至页面。DataPager 支持三种类型的字段:
•    NumericPagerField 显示 1 2 3... 分页界面。
•    NextPreviousPagerField 显示“Next”(下一页)、“Previous”(上一页)、“First”(第一页)和“Last”(最后一页)按钮在行间往复。
•    TemplatePagerField 让您使用 PagerTemplate 定义精确设计和实现分页接口的功能。
一般情况下,采用 DataPager 控件是为任何实现了 IPageableItemContainer 界面的控件(目前 ListView 是唯一实现了该接口的控件)提供分页支持,如下所示:
  复制代码
public interface IPageableItemContainer
{
    event EventHandler<PageEventArgs> TotalRowCountAvailable;
    void SetPageProperties(int startRowIndex, int maximumRows,
                           bool databind);
    int MaximumRows { get; }
    int StartRowIndex { get; }
}
图 7 显示了 ListView、DataPager 与关联的 DataSource 控件之间的关系。DataPager 从不与用于填充 ListView 的 DataSource 直接交互,而是通过该界面查询所需的数据。
 
Figure 7 ListView、DataPager 和 DataSource 之间的关系 (单击该图像获得较大视图)
准备分页时,首先是 ListView 查询 DataSource 以查看其是否支持分页,如果支持,那它是否能够返回总行数。如果能够返回总行数,ListView 将检索数据源中的总行数,然后引发 TotalRowCountAvailable 事件,该事件作为其 IPageableItemContainer 接口一部分实现。任何关联的 DataPager 控件都将订阅该事件,并使用总行数初始化显示分页界面所需的字段。DataPager 将随后调用 ListView 的 SetPageProperties 方法设置初始行索引和要返回的最大行数。
当 ListView 从关联的数据源检索数据时,它将根据 DataPager 设置的值只请求行的子集。无论何时 DataPager 更改其当前页索引(通常由于用户交互),它都将再次调用 ListView 的 SetPageProperties 以反映当前需要检索行的子集。可以通过设置 DataPager 控件的 PageSize 属性来更改一个页面上显示的记录条数,该属性的值将影响相关 ListView 中设置的最大行数信息。
DataPager 还支持 QueryStringField 属性,该属性可以彻底更改 DataPager 的工作方式。通过将 QueryStringField 属性设置为某些字符串(例如 pageNum),表示您请求 DataPager 发送 HTTP GET 请求以响应用户单击页面编号的操作,所请求的页面编号将通过您指定字符串的查询字符串参数发送,而不是通过传统的 POST 回发模式发送。
该变化带来的另一个好处是:它让客户端能够创建到数据绑定 ListView 控件中特定页面的书签,因为可以在 URL 中看到页面编号。请注意,如果切换到这种 GET 通信模式,那由 ASP.NET AJAX UpdatePanel 控件使用的 POST 回发挂接机制将无法截取分页请求,并会将其变为异步回发:
  复制代码
<asp:DataPager ID="_moviesGridDataPager" runat="server"
  QueryStringField="pageNum" >
  <Fields>
    <asp:NumericPagerField />
  </Fields>
</asp:DataPager>
请注意:因为 DataPager 完全依赖 ListView 执行实际的数据分页,而 ListView 又依赖 DataSource 控件,所以对于其它数据绑定控件也存在相同的分页限制。例如,对于 SqlDataSource 控件,仅当其设置为 DataSet 模式时分页才能正常工作,这意味着需要将整个结果集加载到内存中才能执行分页。当然,您可以使用自定义 DataSource 控件或使用 ObjectDataSource 控件自定义自己的分页。
 
排序、编辑、插入和删除
如果 ListView 不具备支持排序和完备的创建、读取、更新和删除 (CRUD) 操作,那么它是不完整的。它实现每种命令的方式与 FormView 控件实现命令的方式相似。
因为 ListView 完全由模板驱动,所以对于其模板中将 CommandName 属性设置为以下七种特定命令字符串之一的按钮,能够予以识别:Cancel(取消)、Delete(删除)、Select(选择)、Edit(编辑)、Insert(插入)、Update(更新)和 Sort(排序)。每个命令都会启动 ListView 中的相应操作——这样如果希望为 ListView 添加排序,那只需要在 LayoutTemplate 中放置一个按钮(图 8 的示例中使用 LinkButton),将其 CommandName 属性设置为 Sort,并将 CommandArgument 设置为希望数据源进行排序的列名称。在图 8 中,我将以前网格中每列的静态标题链接修改为可单击的链接,通过单击该链接可以请求 ListView 根据该列对数据进行排序。
  Figure 8 Sorting in ListView
  复制代码
<asp:ListView ID="_moviesGrid" runat="server" DataKeyNames="movie_id"
  DataSourceID="_moviesDataSource">            
  <LayoutTemplate>
    <div class="PrettyGrid">
      <table cellpadding="0" cellspacing="0" summary="">
        <thead>
          <tr>
            <th scope="col">
              <asp:LinkButton ID="_movieIdSortLink"
                CommandName="Sort" CommandArgument="movie_id"
                runat="server">ID</asp:LinkButton>
            </th>
            <th scope="col">
              <asp:LinkButton ID="_titleSortLink"
                CommandName="Sort" CommandArgument="title"
                runat="server">Title</asp:LinkButton>
            </th>
            <th scope="col">
              <asp:LinkButton ID="_releaseDateSortLink"
                CommandName="Sort" CommandArgument="release_date"
                runat="server">Release date</asp:LinkButton>
            </th>
          </tr>
        </thead>  
    <!-- ... -->
  </LayoutTemplate>
</asp:ListView>
您可以为启动编辑模式、删除行或在数据集中插入新行添加命令按钮,详细过程与其它基于模板的数据绑定控件(如 FormView 和 GridView)基本相同,此处就不再赘述。
 
分组
ListView 的最后一个主要功能是将数据分组成子集的能力,非常类似于 DataList 控件提供的功能。DataList 是表格格式的控件,它可以在所呈现数据表的每个单元格中呈现单行数据。您可以通过设置 RepeatColumns 属性来控制将基础数据集的多少行归入单个表格行中。
由于 ListView 并不仅限于呈现表格,所以它需要更加一般的方式指定将组合呈现的项目组,而这正是 GroupTemplate 提供的方式。图 9 显示了 ListView 中 LayoutTemplate、GroupTemplate 和 ItemTemplate 元素之间的关系。GroupTemplate 可以为基础数据集中每 n 个元素指定外围 HTML,其中 n 的值由 ListView 的 GroupItemCount 属性指定。
 
Figure 9 ListView 中的模板 (单击该图像获得较大视图)
当在 ListView 中使用 GroupTemplate 时,不需要再在 LayoutTemplate 中指定带有 itemPlaceholder ID 的控件——该控件现在需要位于 GroupTemplate 之内。而是需要在 LayoutTemplate 中指定带有 groupPlaceholder ID 的控件(可以通过设置 ListView 的 GroupPlaceholderID 属性更改控件 ID)以说明对于基础数据集中每 n 个项目,应在哪个位置注入 GroupTemplate 的内容。
例如,图 10 中的 ListView 显示了如何通过将 GroupTemplate 定义为搜索行,并将 ItemTemplate 设为仅布局单元格,以在表格的每一行中显示来自数据库的四个电影。结果如图 11 所示。
  Figure 10 Defining Rows with GroupTemplate
  复制代码
<asp:ListView ID="_groupListView" runat="server"
  DataKeyNames="movie_id" DataSourceID="_moviesDataSource"
  GroupItemCount="4" >
  <GroupTemplate>
    <tr>
      <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
    </tr>
  </GroupTemplate>
  <LayoutTemplate>
    <table>
      <asp:PlaceHolder ID="groupPlaceholder" runat="server" />
    </table>
  </LayoutTemplate>
  <ItemTemplate>
    <td>
      movie_id:
      <asp:Label ID="_movie_idLabel" runat="server"
        Text=\'<%# Eval("movie_id") %>\' /> <br />
      title:
      <asp:Label ID="_titleLabel" runat="server"
        Text=\'<%# Eval("title") %>\' /> <br />
      release_date:
      <asp:Label ID="_release_dateLabel" runat="server"
        Text=\'<%# Eval("release_date", "{0:d}") %>\' /> <br />
      <br />
    </td>
  </ItemTemplate>
</asp:ListView>
 
Figure 11 结果 Web 页面中的 GroupTemplate 行 (单击该图像获得较大视图)
这与使用 DataList 完成的工作非常相似,但因为使用的是 ListView,所以可以像前面所示的网格呈现一样轻松添加分页和排序功能,而使用 DataList 完成这些工作则非常复杂。用于本文的下载代码包含实现了分页和排序功能的示例供您参考。
 
开始执行 ListView
您可能希望通过使用 Visual Studio 2008 中的设计器来试用 ListView 控件,该设计器可以提供五种不同的布局供您选择:网格、平铺、项目符号列表、流动和单行。您可以快速查看可用的各种布局选项——但 ListView 真正强大的功能在于您对它所呈现 HTML 的控制,所以在实际的项目中您很可能要自行构建 LayoutTemplate。您是否最后决定今后每次遇到数据绑定都使用 ListView 呢?虽然可能有点过头——但知道您会这样做我还是很高兴。我想今后我还会更多地研究这个灵活的数据绑定控件。
 
Asp.Net WebForm ListView的使用

ListView的搭建步骤:
1.将各个层搭建好,然后添加好引用,最后写好方法。
2.拖ListView控件,然后切换到设计视图。
3.在对象数据源,就是右箭头图标,点击一下。会弹出一个框叫ListView任务。
3.1 选择数据源——新建数据源——对象——下一步

4.配置数据源:
4.1.选择业务对象:例如:BLL.Users,然后下一步。
4.2.定义数据方法:选择相关的方法。例如查询方法,选择GetList()方法。注意,查询 选择用返回值为List集合
的,其他用参数为实体对象的。——完成

然后又回到设计页面,再次点击右上角的三角形图标——配置ListView——

5.选择数据源:有默认的ObjectDataSource1,选择它。
6.配置ListView窗口:
6.配置ListView的布局、样式、选项:
6.1.布局:网格。
6.2.选择样式:蓝调。
6.3.选项:启用所有。注意:不要启用动态数据。在下面的下拉框选择数字页导航。【特别注意,不要选择[启动动态数据]】
6.4.也可以自定义,具体如下:
6.4.1 在前台页面.aspx页面的<asp:ListView>标签里面,打开<LayoutTemplate>标签(模板)。
6.4.2 在第二个<tr>标签里面,就是页面条,可以手动修改文字。
6.4.3 修改样式:<asp:NumericPagerField />
6.4.4 设置每页显示的行数:在<asp:DataPager PageSize="10" ID="DataPager2" runat="server">,表示每页显示10行。
6.4.5 设置是否显示一些按钮:
第一页和最后一页:ShowLastPageButton="true"
显示页码:<asp:NumericPagerField />
上一页:ShowPreviousPageButton="true"
下一页:ShowNextPageButton="true"
FirstPageText="首页"
LastPageText="末页"
6.4 可以复制这段代码替换源代码:
[csharp] view plain copy
1.    <asp:DataPager PagedControlID="ListView1" PageSize="3" ID="DataPager1" runat="server">  
2.        <Fields>  
3.            <asp:NextPreviousPagerField ButtonType="Button"  FirstPageText="首页"  
4.                ShowFirstPageButton="True" ShowLastPageButton="false"  ShowNextPageButton="false" />  
5.      
6.            <asp:NumericPagerField  ButtonType="Button" />  
7.                              
8.            <asp:NextPreviousPagerField ButtonType="Button" LastPageText="末页"   
9.                ShowFirstPageButton="false" ShowPreviousPageButton="false" ShowLastPageButton="true"  ShowNextPageButton="true" />  
10.        </Fields>  
这种方法只适合数据少的时候,因为查数据的时候,是把数据全部查出来,加载到服务器内存,这样服务器负担很重。




用另外一种方法解决:
一、在<asp:ObjectDataSource>标签里面添加如下:
1.EnablePaging="true" 启用分页 查询的意思。
2.SelectMethod="GetList" 启用分页查询的方法。
3.MaximumRowsParameterName="pageSize" 页容量(一页显示几行)。
4.StatrRowIndexParameterName="startRowIndex" 起始页的下标(比如每页3行,第2页就传4)。
5.SelectCountMethod="GetRowCount" 获取总行数方法。

二、在BLL层添加:
1.在BLL层把这两个参数传入GetList()方法。为:GetList(int pageSize,int startRowIndex)。
例子://           5   10
[csharp] view plain copy
1.    public IList<LeaveWordBorad.MODEL.Users> GetList(int pageSize,int startRowIndex)  
2.    {  
3.        string strSql = "select * from (select *,Row_Number() over(order by uid) rownum FROM Users) t where t.rownum>" + startRowIndex + " and t.rownum<=" + (startRowIndex + pageSize);  
4.        DataTable dt = DbHelperSQL.GetDataTable(strSql);  
5.        IList<MODEL.Users> list = Table2List(dt);  
6.        return list;  
7.    }//所谓高效分页  


2.添加获取总行数方法
public int GetRowCount();
例子:
[csharp] view plain copy
1.    public int GetRowCount()  
2.    {  
3.        return Convert.ToInt32(DbHelperSQL.ExcuteScalar("select count(*) from users"));  
4.    }  


注意:如果出现错误,凡是跟源数据相关的,都是跟程序集相关。可以将引用删除重新加一下。也可以重新配置一下。
特别注意,不要启用动态数据。

C# ListView用法详解 很完整
分类:.NET-基础知识+WinFrom
一、ListView类
          1、常用的基本属性:
        (1)FullRowSelect:设置是否行选择模式。(默认为false) 提示:只有在Details视图该属性才有意义。
        (2) GridLines:设置行和列之间是否显示网格线。(默认为false)提示:只有在Details视图该属性才有意义。
        (3)AllowColumnReorder:设置是否可拖动列标头来对改变列的顺序。(默认为false)提示:只有在Details视图该属性才有意义。
        (4)View:获取或设置项在控件中的显示方式,包括Details、LargeIcon、List、SmallIcon、Tile(默认为 LargeIcon)
        (5)MultiSelect:设置是否可以选择多个项。(默认为false)
        (6)HeaderStyle:获取或设置列标头样式。
                  Clickable:列标头的作用类似于按钮,单击时可以执行操作(例如排序)。
                  NonClickable:列标头不响应鼠标单击。
                  None:不显示列标头。

        (7)LabelEdit:设置用户是否可以编辑控件中项的标签,对于Detail视图,只能编辑行第一列的内容。(默认为false)
        (8)CheckBoxes:设置控件中各项的旁边是否显示复选框。(默认为false)
        (9)LargeImageList:大图标集。提示:只在LargeIcon视图使用。
        (10)SmallImageList:小图标集。提示:只有在SmallIcon视图使用。
        (11)StateImageList:图像蒙板。这些图像蒙板可用作LargeImageList和SmallImageList图像的覆盖图,这些图像可用于指示项的应用程序定义的状态。(暂时不大懂)
        (12)SelectedItems:获取在控件中选定的项。
        (13)CheckedItems:获取控件中当前复选框选中的项。
        (14)Soritng:对列表视图的项进行排序。(默认为None)
                    Ascending:项按递增顺序排序。
                    Descending:项按递减顺序排序。
                    None:项未排序。
         (15)Scrollable:设置当没有足够空间来显示所有项时是否显示滚动条。(默认为true)
         (16)HoverSelection:设置当鼠标指针悬停于项上时是否自动选择项。(默认为false)
         (17)HotTracking:设置当鼠标指针经过项文本时,其外观是否变为超链接的形式。(默认为false)
         (18)HideSelection:设置选定项在控件没焦点时是否仍突出显示。(默认为false)
         (19)ShowGroups:设置是否以分组方式显示项。(默认为false);
         (20)Groups:设置分组的对象集合。
          (21)TopItem:获取或设置控件中的第一个可见项,可用于定位。(效果类似于EnsureVisible方法)
           2、常用方法:
          (1)BeginUpdate:避免在调用EndUpdate 方法之前描述控件。当插入大量数据时,可以有效地避免控件闪烁,并能大大提高速度。
          (2)EndUpdate:在BeginUpdate 方法挂起描述后,继续描述列表视图控件。(结束更新)
          (3)EnsureVisible:列表视图滚动定位到指定索引项的选项行。(效果类似于TopItem属性)
          (4)FindItemWithText:查找以给定文本值开头的第一个 ListViewItem。
           (5)FindNearestItem:按照指定的搜索方向,从给定点开始查找下一个项。提示:只有在LargeIcon或SmallIcon视图才能使用该方法。
            3、常用事件:
         (1)AfterLabelEdit:当用户编辑完项的标签时发生,需要LabelEdit属性为true。
         (2)BeforeLabelEdit:当用户开始编辑项的标签时发生。
         (3)ColumnClick:当用户在列表视图控件中单击列标头时发生。
   二、ListView的五种视图:
        1、LargeIcon:每个项都显示为一个最大化图标,在它的下面有一个标签。(效果见下图)
         2、SmallIcon:每个项都显示为一个小图标,在它的右边带一个标签。(效果见下图)
         3、List:每个项都显示为一个小图标,在它的右边带一个标签。各项排列在列中,没有列标头。(效果见下图)
         4、Details:可以显示任意的列,但只有第一列可以包含一个小图标和标签,其它的列项只能显示文字信息,有列表头。(效果见下图)
         5、Tile:每个项都显示为一个完整大小的图标,在它的右边带项标签和子项信息。(只有Windows XP 和 Windows Server 2003 系列支持)
        ①Details视图:
            this.listView1.SmallImageList = this.imageList1;  //将listView的图标集与imageList1绑定
         (1)列表头创建(记得,需要先创建列表头)       
[csharp] view plaincopy
1.    ColumnHeader  ch= new ColumnHeader();
2.    
3.    nbsp;ch.Text = "列标题1";   //设置列标题
4.    
5.    ch.Width = 120;    //设置列宽度
6.    
7.    ch.TextAlign = HorizontalAlignment.Left;   //设置列的对齐方式
8.    
9.    this.listView1.Columns.Add(ch);    //将列头添加到ListView控件。
[csharp] view plain copy
1.    ColumnHeader  ch= new ColumnHeader();  
2.      
3.    ch.Text = "列标题1";   //设置列标题  
4.      
5.    ch.Width = 120;    //设置列宽度  
6.      
7.    ch.TextAlign = HorizontalAlignment.Left;   //设置列的对齐方式  
8.      
9.    this.listView1.Columns.Add(ch);    //将列头添加到ListView控件。  
                          或者
[csharp] view plaincopy
1.    this.listView1.Columns.Add("列标题1", 120,  HorizontalAlignment.Left); //一步添加
[csharp] view plain copy
1.    this.listView1.Columns.Add("列标题1", 120,  HorizontalAlignment.Left); //一步添加  
       (2)添加数据项       
[csharp] view plaincopy
1.    this.listView1.BeginUpdate();   //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度
2.    
3.    for (int i = 0; i < 10; i++)   //添加10行数据
4.    {
5.         ListViewItem lvi = new ListViewItem();
6.    
7.         lvi.ImageIndex = i;     //通过与imageList绑定,显示imageList中第i项图标
8.    
9.         lvi.Text = "subitem" + i;
10.    
11.         lvi.SubItems.Add("第2列,第"+i+"行");
12.    
13.         lvi.SubItems.Add("第3列,第"+i+"行");
14.    
15.         this.listView1.Items.Add(lvi);
16.    }
17.    
18.    this.listView1.EndUpdate();  //结束数据处理,UI界面一次性绘制。
[csharp] view plain copy
1.    this.listView1.BeginUpdate();   //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度  
2.      
3.    for (int i = 0; i < 10; i++)   //添加10行数据  
4.    {  
5.        ListViewItem lvi = new ListViewItem();  
6.      
7.        lvi.ImageIndex = i;     //通过与imageList绑定,显示imageList中第i项图标  
8.      
9.        lvi.Text = "subitem" + i;  
10.      
11.        lvi.SubItems.Add("第2列,第"+i+"行");  
12.      
13.        lvi.SubItems.Add("第3列,第"+i+"行");  
14.      
15.        this.listView1.Items.Add(lvi);  
16.    }  
17.      
18.    this.listView1.EndUpdate();  //结束数据处理,UI界面一次性绘制。  
          (3)显示项
[csharp] view plaincopy
1.    foreach (ListViewItem item in this.listView1.Items)
2.    {
3.          for (int i = 0; i < item.SubItems.Count; i++)
4.          {
5.              MessageBox.Show(item.SubItems[i].Text);
6.          }
7.    }
[csharp] view plain copy
1.    foreach (ListViewItem item in this.listView1.Items)  
2.    {  
3.          for (int i = 0; i < item.SubItems.Count; i++)  
4.          {  
5.              MessageBox.Show(item.SubItems[i].Text);  
6.          }  
7.    }  
           (4)移除某项
[csharp] view plaincopy
1.    foreach (ListViewItem lvi in listView1.SelectedItems)  //选中项遍历
2.    {
3.          listView1.Items.RemoveAt(lvi.Index); // 按索引移除
4.          //listView1.Items.Remove(lvi);   //按项移除
5.    }    
[csharp] view plain copy
1.    foreach (ListViewItem lvi in listView1.SelectedItems)  //选中项遍历  
2.    {  
3.          listView1.Items.RemoveAt(lvi.Index); // 按索引移除  
4.          //listView1.Items.Remove(lvi);   //按项移除  
5.    }     
          (5)行高设置(利用imageList实现)
[csharp] view plaincopy
1.    ImageList imgList = new ImageList();
2.    
3.    imgList.ImageSize = new Size(1, 20);// 设置行高 20 //分别是宽和高
4.    
5.    listView1.SmallImageList = imgList; //这里设置listView的SmallImageList ,用imgList将其撑大
[csharp] view plain copy
1.    ImageList imgList = new ImageList();  
2.      
3.    imgList.ImageSize = new Size(1, 20);// 设置行高 20 //分别是宽和高  
4.      
5.    listView1.SmallImageList = imgList; //这里设置listView的SmallImageList ,用imgList将其撑大  
          (6)清空
[csharp] view plaincopy
1.    this.listView1.Clear();  //从控件中移除所有项和列(包括列表头)。
2.    
3.    this.listView1.Items.Clear();  //只移除所有的项。
[csharp] view plain copy
1.    this.listView1.Clear();  //从控件中移除所有项和列(包括列表头)。  
2.      
3.    this.listView1.Items.Clear();  //只移除所有的项。  
运行效果:
 
        ②largeIcon视图:
[csharp] view plaincopy
1.    this.listView1.View = View.LargeIcon;
2.    
3.    this.listView1.LargeImageList = this.imageList2;
4.    
5.    this.listView1.BeginUpdate();
6.    
7.    for (int i = 0; i < 10; i++)
8.    {
9.          ListViewItem lvi = new ListViewItem();
10.    
11.          lvi.ImageIndex = i;
12.    
13.          lvi.Text = "item" + i;
14.    
15.          this.listView1.Items.Add(lvi);
16.    }
17.    
18.    this.listView1.EndUpdate();
[csharp] view plain copy
1.    this.listView1.View = View.LargeIcon;  
2.      
3.    this.listView1.LargeImageList = this.imageList2;  
4.      
5.    this.listView1.BeginUpdate();  
6.      
7.     for (int i = 0; i < 10; i++)  
8.     {  
9.          ListViewItem lvi = new ListViewItem();  
10.      
11.          lvi.ImageIndex = i;  
12.      
13.          lvi.Text = "item" + i;  
14.      
15.          this.listView1.Items.Add(lvi);  
16.     }  
17.      
18.     this.listView1.EndUpdate();  
运行效果:

 
          ③SmallIcon视图:
[csharp] view plaincopy
1.    this.listView1.View = View.SmallIcon;
2.    
3.    this.listView1.SmallImageList= this.imageList1;
4.    
5.    this.listView1.BeginUpdate();
6.    
7.    for (int i = 0; i < 10; i++)
8.    {
9.         ListViewItem lvi = new ListViewItem();
10.    
11.          lvi.ImageIndex = i;
12.    
13.          lvi.Text = "item" + i;
14.    
15.          this.listView1.Items.Add(lvi);
16.    }
17.    
18.    this.listView1.EndUpdate();
[csharp] view plain copy
1.    this.listView1.View = View.SmallIcon;  
2.      
3.    this.listView1.SmallImageList= this.imageList1;  
4.      
5.    this.listView1.BeginUpdate();  
6.      
7.    for (int i = 0; i < 10; i++)  
8.    {  
9.         ListViewItem lvi = new ListViewItem();  
10.      
11.          lvi.ImageIndex = i;  
12.      
13.          lvi.Text = "item" + i;  
14.      
15.          this.listView1.Items.Add(lvi);  
16.    }  
17.      
18.    this.listView1.EndUpdate();  
运行效果:

 
           ④List视图:   
[csharp] view plaincopy
1.    this.listView1.View = View.List;
2.    
3.    this.listView1.SmallImageList= this.imageList1;
4.    
5.    this.listView1.BeginUpdate();
6.    
7.    for (int i = 0; i < 10; i++)
8.    {
9.         ListViewItem lvi = new ListViewItem();
10.    
11.         lvi.ImageIndex = i;
12.    
13.         lvi.Text = "item" + i;
14.    
15.         this.listView1.Items.Add(lvi);
16.    }
17.    
18.    this.listView1.EndUpdate();
[csharp] view plain copy
1.    this.listView1.View = View.List;  
2.      
3.    this.listView1.SmallImageList= this.imageList1;  
4.      
5.    this.listView1.BeginUpdate();  
6.      
7.    for (int i = 0; i < 10; i++)  
8.    {  
9.         ListViewItem lvi = new ListViewItem();  
10.      
11.         lvi.ImageIndex = i;  
12.      
13.         lvi.Text = "item" + i;  
14.      
15.         this.listView1.Items.Add(lvi);  
16.    }  
17.      
18.    this.listView1.EndUpdate();  
运行效果:

 
     三、其它应用
         1、分组:      
[csharp] view plaincopy
1.    ListViewGroup man_lvg = new ListViewGroup();  //创建男生分组
2.    
3.    man_lvg.Header = "男生";  //设置组的标题。
4.    
5.    //man_lvg.Name = "man";   //设置组的名称。
6.    
7.    man_lvg.HeaderAlignment = HorizontalAlignment.Left;   //设置组标题文本的对齐方式。(默认为Left)
8.    
9.    ListViewGroup women_lvg = new ListViewGroup();  //创建女生分组
10.    
11.    women_lvg.Header = "女生";
12.    
13.    //women_lvg.Name = "women";
14.    
15.    women_lvg.HeaderAlignment = HorizontalAlignment.Center;   //组标题居中对齐
16.    
17.    this.listView1.Groups.Add(man_lvg);    //把男生分组添加到listview中
18.    
19.    this.listView1.Groups.Add(women_lvg);   //把男生分组添加到listview中
20.    
21.    this.listView1.ShowGroups = true;  //记得要设置ShowGroups属性为true(默认是false),否则显示不出分组
22.    
23.    for (int i = 0; i < 5; i++)
24.    {
25.         ListViewItem lvi = new ListViewItem();
26.    
27.         lvi.ImageIndex = i;
28.    
29.         lvi.Text = "item"+i;
30.    
31.         lvi.ForeColor = Color.Blue;  //设置行颜色
32.    
33.         lvi.SubItems.Add("第2列,第"+i+"行");
34.    
35.         lvi.SubItems.Add("第3列,第"+i+"行");
36.    
37.         man_lvg.Items.Add(lvi);   //分组添加子项
38.    
39.         // 或 lvi.Group = man_lvg;  //分组添加子项
40.    
41.         this.listView1.Items.Add(lvi);
42.    }
[csharp] view plain copy
1.     ListViewGroup man_lvg = new ListViewGroup();  //创建男生分组  
2.      
3.     man_lvg.Header = "男生";  //设置组的标题。  
4.      
5.     //man_lvg.Name = "man";   //设置组的名称。  
6.      
7.     man_lvg.HeaderAlignment = HorizontalAlignment.Left;   //设置组标题文本的对齐方式。(默认为Left)  
8.      
9.     ListViewGroup women_lvg = new ListViewGroup();  //创建女生分组  
10.      
11.     women_lvg.Header = "女生";  
12.      
13.     //women_lvg.Name = "women";  
14.      
15.     women_lvg.HeaderAlignment = HorizontalAlignment.Center;   //组标题居中对齐  
16.      
17.     this.listView1.Groups.Add(man_lvg);    //把男生分组添加到listview中  
18.      
19.     this.listView1.Groups.Add(women_lvg);   //把男生分组添加到listview中  
20.      
21.     this.listView1.ShowGroups = true;  //记得要设置ShowGroups属性为true(默认是false),否则显示不出分组  
22.      
23.     for (int i = 0; i < 5; i++)  
24.     {  
25.         ListViewItem lvi = new ListViewItem();  
26.      
27.         lvi.ImageIndex = i;  
28.      
29.         lvi.Text = "item"+i;  
30.      
31.         lvi.ForeColor = Color.Blue;  //设置行颜色  
32.      
33.         lvi.SubItems.Add("第2列,第"+i+"行");  
34.      
35.         lvi.SubItems.Add("第3列,第"+i+"行");  
36.      
37.         man_lvg.Items.Add(lvi);   //分组添加子项  
38.      
39.         // 或 lvi.Group = man_lvg;  //分组添加子项  
40.      
41.         this.listView1.Items.Add(lvi);  
42.    }  
运行效果:
 
          2、查找文本(只能查找到匹配前缀的文本且只能找出第一个符合的项):
[csharp] view plaincopy
1.    ListViewItem foundItem=this.listView1.FindItemWithText(this.textBox1.Text,true,0);    //参数1:要查找的文本;参数2:是否子项也要查找;参数3:开始查找位置
2.    
3.    if (foundItem != null)
4.    {
5.    
6.       this.listView1.TopItem = foundItem;  //定位到该项
7.    
8.       foundItem.ForeColor = Color.Red;   
9.    }


分类:

技术点:

相关文章: