1. 程式人生 > >【Asp.net之旅】--資料繫結控制元件之DataList

【Asp.net之旅】--資料繫結控制元件之DataList

       上篇部落格討論了Repeater控制元件的基本用法,它是最基本的資料繫結控制元件,只提供了資料繫結的功能,熟練運用Repeater控制元件後,其它類似的資料繫結控制元件就很簡單了。接著我們上篇部落格的內容繼續,今天來討論下DataList的基本使用方法。

一、繫結控制元件之DataList


       該控制元件可以以自定義的格式顯示各種資料來源的欄位,其顯示資料的格式在建立的模板中定義,可以為項、交替項、選定項和編輯項建立模板。該控制元件也可以使用標題、腳註和分隔符模板自定義整體外觀,還可以一行顯示多個數據行。雖然DataList控制元件擁有很大的靈活性,但其本身不支援資料分頁,程式設計者需要通過自己編寫方法完成分頁的功能。僅用於資料的顯示,不支援編輯、插入、刪除。
       優點:自定義格式顯示資料、比較靈活。
       缺點:不支援分頁,編輯插入。

   1、DataList簡介


        上文說到DataList控制元件不僅能夠靈活的顯示資料,而且還支援編輯、插入、刪除操作。想要顯示資料基本的模板是必不可少的,相同的該控制元件也為開發人員提供了基本的模板使用。另外DataList不但提供了基本的ItemCommand事件,而且還封裝了刪除、取消、編輯、更新事件。通過將資料繫結到EditItemTemplate模板中能夠容易的進入編輯狀態,具體方法將會在下文中講到。


        對於基本的模板和事件的使用方法上篇文章已經討論,在此將不會深入的討論。

二、控制元件使用技巧

 1、基本操作--增刪改

      下面的程式碼示例使用Asp.net實現,能夠對資料進行增加、刪除、修改。DataList控制元件封裝了基本的刪除和修改模板,但沒有繼承插入功能,示例中的插入使用的是Asp.net的Literal控制元件來實現的,具體實現方法如下。
      刪除頁面:

    新增頁面:


    編輯頁面:



      前臺程式碼:和Repeater控制元件基本用法相同,不同的是新增加了編輯模板,在編輯模板中綁定了資料,在進行編輯操作時只要跳轉到編輯模板即可。程式碼中在基本模板ItemTemplate中添加了Literal控制元件,當點選新增按鈕時再後臺動態的新增新行,並在新行中新增資料控制元件。具體後臺程式碼如下。

<div>
    <asp:DataList ID="DataList1" runat="server" OnItemCommand="DataList1_ItemCommand" OnCancelCommand="DataList1_CancelCommand" OnUpdateCommand="DataList1_UpdateCommand" OnEditCommand="DataList1_EditCommand" OnDeleteCommand="DataList1_DeleteCommand">
        <HeaderTemplate>
            <table border="1px" cellpadding="1px" cellspacing="5px" style="text-align:center;border-collapse:collapse;border-color:red;">
                <tr style="background-color:yellow;">    
                    <th>ID</th>
                    <th>內容</th>
                    <th>編輯</th>
                </tr>
        </HeaderTemplate>
        <ItemTemplate>
            <tr onmouseover="backcolor=this.style.backgroundColor;this.style.backgroundColor='#6699ff'" onmouseout="this.style.backgroundColor=backcolor">
                <td><%# Eval("id") %></td>
                <td><%# Eval("name") %></td>
                <td>
                    <asp:LinkButton ID="lbtDelete" runat="server" CommandName="Delete" CommandArgument='<%#Eval("id") %>'>刪除</asp:LinkButton>
                    <asp:LinkButton ID="lbtEdit" runat="server" CommandName="Edit" CommandArgument='<%#Eval("name") %>'>編輯</asp:LinkButton>
                    <asp:LinkButton ID="lbtAdd" runat="server" CommandName="Add">新增</asp:LinkButton>
                </td>
            </tr>
            <!--新增新行時動態新增文字框-->
            <asp:Literal ID="litAdd" runat="server"></asp:Literal>              
        </ItemTemplate>
            
        <EditItemTemplate>
            <tr>
                <td>
                    <asp:TextBox ID="id" runat="server" Text='<%#Eval("id") %>'></asp:TextBox>
                </td>
                <td>
                    <asp:TextBox ID="name" runat="server" Text='<%#Eval("name") %>'></asp:TextBox>
                </td>
                <td>
                    <asp:LinkButton ID="lbtCancel" runat="server" Text="取消" CommandName="Cancel"></asp:LinkButton>
                    <asp:LinkButton ID="lbtUpdate" runat="server" Text="更新" CommandName="Update"  CommandArgument='<%#Eval("id") %>'></asp:LinkButton>
                </td>
            </tr>
                
        </EditItemTemplate>
        <FooterTemplate>
            </table>
        </FooterTemplate>
    </asp:DataList>

    <!--分頁控制元件-->
    <div class="pageBar">
        <asp:Literal ID="lit" runat="server"></asp:Literal>
    </div>
</div>

       後臺程式碼:新增新行的操作是在ItemCommand事件中指定的,將新行的程式碼新增到Literal控制元件上實現了新增新行,併為新行指定控制元件。另外的基本編輯命令是在單獨的事件中編寫的,因為DataList為開發人員提供了基本的操作事件,如果想要進入某一個狀態只需要將狀態的ItemIndex值。

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        string strName = string.Empty;  //宣告新增的內容

        try
        {
            //獲取需要新增的內容
            strName = Request.QueryString["name"].ToString();
        }
        catch
        {

        }

        //判斷如果要新增的內容不為空將會進行新增操作
        if (strName!=string.Empty)
        {
            this.Insert(strName);
        }

        //**********************************************************************
        //分頁效果實現
        PagedDataSource pds = new PagedDataSource(); //宣告分頁類
        //設定分頁屬性
        pds.AllowPaging = true;
        pds.PageSize = 3;
        pds.DataSource = this.GetDT().DefaultView;
        pds.CurrentPageIndex = pageIndex - 1;
        //**********************************************************************

        //繫結分頁資料來源
        this.DataList1.DataSource = pds;
        this.DataList1.DataBind();
    }
}

/// <summary>
/// 新增新的資料行內容
/// </summary>
/// <param name="strName">獲取要插入的內容</param>
private void Insert(string strName) {
    //向資料庫中插入新內容
    using (SqlConnection con = this.GetSqlCon())
    {
        con.Open(); //開啟資料庫連線
        //設定命令物件
        SqlCommand sqlcom = new SqlCommand();
        sqlcom.Connection = con;
        sqlcom.CommandText = "insert match values(@name)";
        //新增引數
        sqlcom.Parameters.Add(new SqlParameter("@name", strName));
        //執行插入
        sqlcom.ExecuteNonQuery();
    }
}

/// <summary>
/// 獲取繫結的資料來源
/// </summary>
/// <returns>DataTable,從match表中獲取的內容</returns>
private DataTable GetDT()
{
    DataTable dt = new DataTable(); //宣告資料庫表
    //獲取資料來源
    using (SqlConnection con = this.GetSqlCon())
    {
        con.Open();
        //宣告資料來源命令
        SqlCommand sqlCom = new SqlCommand();
        sqlCom.CommandText = "select * from match";
        sqlCom.Connection = con;
        SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCom);
        SqlCommandBuilder sqlCb = new SqlCommandBuilder(sqlDa);
        sqlDa.Fill(dt);
    }

    return dt;
}

/// <summary>
/// 宣告資料庫連結物件
/// </summary>
/// <returns>SqlConnection,返回資料庫連線物件</returns>
private SqlConnection GetSqlCon()
{
    SqlConnection sqlCon = new SqlConnection("server=.;database=myblog;uid=sa;pwd=1");
    return sqlCon;
}

/// <summary>
/// 編輯命令事件
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
protected void DataList1_EditCommand(object source, DataListCommandEventArgs e)
{
    this.DataList1.EditItemIndex = e.Item.ItemIndex;    //設定編輯的索引行
    //重新繫結資料來源
    this.DataList1.DataSource = this.GetDT();
    this.DataList1.DataBind();
}

/// <summary>
/// 刪除命令事件
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
protected void DataList1_DeleteCommand(object source, DataListCommandEventArgs e)
{
    if (e.CommandName == "Delete")
    {
        string id = e.CommandArgument.ToString();   //獲取要刪除行的id號
        //執行刪除命令
        using (SqlConnection con = this.GetSqlCon())
        {
            con.Open();

            SqlCommand sqlcom = new SqlCommand();
            sqlcom.Connection = con;
            sqlcom.CommandText = "delete from match where [email protected]";

            sqlcom.Parameters.Add(new SqlParameter("@id", id));
            sqlcom.ExecuteNonQuery();
        }

        //重新繫結資料
        this.DataList1.DataSource = this.GetDT();
        this.DataList1.DataBind();
    }
}

/// <summary>
/// 取消更新事件
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
protected void DataList1_CancelCommand(object source, DataListCommandEventArgs e)
{
    if (e.CommandName == "Cancel")
    {
        this.DataList1.EditItemIndex = -1;
        //重新繫結資料
        this.DataList1.DataSource = this.GetDT();
        this.DataList1.DataBind();
    }
}

/// <summary>
/// 更新按鈕事件
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
protected void DataList1_UpdateCommand(object source, DataListCommandEventArgs e)
{
    //判斷如果是更新命令的話,將會執行更新命令
    if (e.CommandName == "Update")
    {
        int intId = int.Parse(e.CommandArgument.ToString()); //獲取更新行的索引號
        string strname = ((TextBox)e.Item.FindControl("name")).Text;    //獲取更新的內容

        //更新資料庫中的值
        using (SqlConnection sqlcon = this.GetSqlCon())
        {
            sqlcon.Open();
            SqlCommand sqlcom = new SqlCommand();
            sqlcom.CommandText = "update match set nam[email protected] where [email protected]";
            sqlcom.Connection = sqlcon;

            SqlParameter[] sqlParam = new SqlParameter[] { new SqlParameter("@name", strname), new SqlParameter("@id", intId) };
            sqlcom.Parameters.AddRange(sqlParam);

            sqlcom.ExecuteNonQuery();

        }
        //更新完成後跳轉頁面
        this.DataList1.EditItemIndex = -1;
        //重新繫結資料
        this.DataList1.DataSource = this.GetDT();
        this.DataList1.DataBind();

    }
}

/// <summary>
/// 事件回發命令
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
    //判斷如果命令名稱為Add,將會新增新行
    if (e.CommandName == "Add")
    {
        Literal lit = (Literal)e.Item.FindControl("litAdd");    //獲取頁面的物件

        //向頁面中新增新行標籤
        StringBuilder strAdd = new StringBuilder("<tr><td><input type=\"text\" id=\"45\"></td><td><input type=\"text\" id='name' onchange='InputKey()'></td>");
        strAdd.Append("<td><a href='Default.aspx' id='CancelInsert'>取消</a>");
        strAdd.Append("<a id='ok'>確認</a>");
        strAdd.Append("</td></tr>");

        //將新行標籤日俺家到html中
        lit.Text = strAdd.ToString();
    }
}

 2、分頁實現


      分頁的實現效果和Repeater控制元件分頁類似。在前臺頁面中新增Literal控制元件,並在後臺使用PagedataSource類將資料進行分頁。
      前臺程式碼:在頁面的最後添加了一個分頁的div標記,並在div中添加了Literal控制元件,控制元件中標籤的連結地址是在後臺動態指定的。

<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.7.1.js"></script>
    
    <script type="text/javascript" language="javascript">

        $(function () {
            $("#ok").css("text-decoration", "underline").css("color", "blue");  
            $("#CancelInsert").attr("href","Default.aspx");
        });

        function InputKey() {
            var vartext = document.getElementById("name").value;
            $("#ok").attr("href","Default.aspx?name=" + vartext);       
        }      
    </script>

    <style type="text/css">
        .pageBar {
            margin-top:50px;
        }
        .pageBar a{
            margin-top:50px;
            margin-left:20px;
            border-collapse:collapse;
            border:solid 1px black;
            background-color:#fbf9f9;
            padding:4px 4px 4px 4px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        
        <div>
            <!--分頁控制元件-->
            <div class="pageBar">
                <asp:Literal ID="lit" runat="server"></asp:Literal>
            </div>
        </div>
    </form>
</body>
</html>


      後臺程式碼:每次向後臺請求資料都會重新為<a>標籤指定連結頁面的地址,這樣能夠使得PagedataSource能夠連結到想要的頁面。

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        int pageIndex = 1;  //宣告頁索引
        try
        {
            //獲取要跳轉頁的索引號    
            pageIndex = int.Parse(Request.QueryString["Page"].ToString());
            //如果是第零頁,將會賦值為第一頁
            if (pageIndex<0)
            {
                pageIndex = 1;
            }
        }
        catch
        {
            //預設顯示的是第一頁
            pageIndex = 1;
        }

        //判斷如果要新增的內容不為空將會進行新增操作
        if (strName!=string.Empty)
        {
            this.Insert(strName);
        }

        //**********************************************************************
        //分頁效果實現
        PagedDataSource pds = new PagedDataSource(); //宣告分頁類
        //設定分頁屬性
        pds.AllowPaging = true;
        pds.PageSize = 3;
        pds.DataSource = this.GetDT().DefaultView;
        pds.CurrentPageIndex = pageIndex - 1;
        //**********************************************************************

        //繫結分頁資料來源
        this.DataList1.DataSource = pds;
        this.DataList1.DataBind();
        //新增分頁標籤
        this.lit.Text = this.GetPageBar(pds);
    }
}
/// <summary>
/// 新增並設定分頁命令
/// </summary>
/// <param name="pds">分頁資料來源</param>
/// <returns>包含分頁連線的a標籤</returns>
private string GetPageBar(PagedDataSource pds) {
    string Page = string.Empty;
    int intCurrent = pds.CurrentPageIndex + 1;

    //設定首頁連結地址
    if (intCurrent==1)
    {
        Page += "<a href=\"javascript:void(0)\">首頁</a>";// 轉義字元:\"為雙引號
    }
    else
    {
        Page += "<a href=\"" + Request.CurrentExecutionFilePath + "?Page=1\">首頁</a>";
    }

    //設定上一頁連結地址
    if ((intCurrent-1)<1)
    {
        Page += "<a href=\"javascript:void(0)\">上一頁</a>";
    }
    else
    {
        Page += "<a href=\"" + Request.CurrentExecutionFilePath + "?Page=" + (intCurrent - 1) + "\">上一頁</a>";
    }

    //設定下一頁連結地址
    if ((intCurrent+1)>pds.PageCount)
    {
        Page +="<a href=\"javascript:void(0)\">下一頁</a>";
    }
    else
    {
            Page +="<a href=\""+Request.CurrentExecutionFilePath +"?Page="+(intCurrent+1)+"\">下一頁</a>";   
    }

    //設定末頁的連結
    if (intCurrent==pds.PageCount)
	{
        Page += "<a href=\"javascript:void(0)\">末頁</a>";
    }
    else
    {
        Page += "<a href=\"" + Request.CurrentExecutionFilePath + "?Page=" + pds.PageCount + "\">末頁</a>";
    }

    return Page;    //返回也標籤
}

具體程式碼示例,請下載:DataList示例

三、對比昇華

       結合前篇文章來對比下這兩個資料繫結控制元件,對於Repeater控制元件它是微軟開發的最基礎的繫結控制元件只為開發人員提供了基本的事件流和基本的模板,各個子項完全可以由開發人員自己編寫,而且不會生成冗餘程式碼,唯一美中不足的是微軟沒封裝向分頁、編輯之類的功能,想要實現該功能必須自己編寫了。

       相較Repeater控制元件,DataList控制元件不僅在Repeater基礎上封裝了編輯、刪除、更新、取消之類的事件,而且還添加了Selectedtemplate模板,能夠在後臺程式碼中編寫被選中行的顯示效果,而且應用靈活,美中不足的是它也沒有封裝分頁、插入的功能,只能由開發人員自己編寫了,另外採用視覺化視窗設計DataList樣式後會生成冗餘的程式碼,不便於閱讀。

       總之在使用時它們兩個各有利弊,如果只想繫結和顯示資料那Repeater控制元件當然是我們的首選,當然如果有編輯、刪除之類的操作,並想提前設計繫結樣式的話不妨使用DataList。

結語

        對比兩個控制元件它們都有優缺點,那是不是就沒有較完美一些的繫結控制元件了呢?當然不是,.NET封裝了多個數據繫結控制元件,上面的兩種是在程式設計中經常用到的,真正功能齊全的是ListView控制元件,它的使用我們將會在下篇文章中著重討論。

相關推薦

Asp.net--資料控制元件Repeater

引言         前幾篇的文章在說AJAX的內容,利用AJAX技術能夠開發出高效執行的網站應用程式,不過在進行B/S專案開發時只擁有AJAX技術是遠遠不夠的,踏入到B/S要學的東西會更多,但相較C/S的複雜邏輯結構來說B/S在開發時還是很簡單的。         在開

Asp.net--資料控制元件DataList

       上篇部落格討論了Repeater控制元件的基本用法,它是最基本的資料繫結控制元件,只提供了資料繫結的功能,熟練運用Repeater控制元件後,其它類似的資料繫結控制元件就很簡單了。接著我們上篇部落格的內容繼續,今天來討論下DataList的基本使用方法。

asp net夜話資料控制元件

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Asp.Net--DropDownList與DataTable資料的方法(C#)[學習筆記]

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default"%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transi

ASP.NET資料控制元件

資料繫結控制元件簡介 資料繫結分為:資料來源 和 資料繫結控制元件 兩部分,資料繫結控制元件通過資料來源來獲得資料,通過資料來源來 隔離資料提供者和資料使用者,資料來源有: SqlDataSource,AccessDataSource,ObjectDataSource,L

ASP.Net資料控制元件小結

  資料繫結作為ASP.Net中較為重要的一個知識點,其中涉及到了三個重要的資料繫結控制元件,Repeater DataList和GridView(DataGrid)。 Repeater控制元件:   特點:     顧名思義 就是重複繫結資料的控制元件,它沒有內建佈局。

Silverlight自定義資料控制元件應該如何處理IEditableObject和IEditableCollectionView物件

原文: Silverlight自定義資料繫結控制元件應該如何處理IEditableObject和IEditableCollectionView物件 原創文章,如需轉載,請註明出處。   最近在一直研究Silverlight下的資料繫結控制元件,發現有這樣兩個介面IEditableObject

asp.net core 系列8 實戰 利用 EF Core 完成資料操作層的實現

# 0. 前言 通過前兩篇,我們建立了一個專案,並規定了一個基本的資料層訪問介面。這一篇,我們將以EF Core為例演示一下資料層訪問介面如何實現,以及實現中需要注意的地方。 # 1. 新增EF Core 先在資料層實現層引入 EF Core: ```bash cd Domain.Implements

asp.net core 系列6 實戰 一個專案的完整結構

# 0. 前言 在《asp.net core 系列》之前的幾篇文章中,我們簡單瞭解了路由、控制器以及檢視的關係以及靜態資源的引入,讓我們對於asp.net core mvc專案有了基本的認識。不過,這些並不是 asp.net core mvc專案的全部內容,剩下的內容我將結合實戰專案為大家講解其中的知識。現

asp.net core 系列10 實戰ActionFilter

# 0.前言 在上一篇中,我們提到了如何建立一個UnitOfWork並通過ActionFilter設定啟用。這一篇我們將簡單介紹一下ActionFilter以及如何利用ActionFilter,順便補齊一下上一篇的工具類。 # 1. ActionFilter 介紹 ActionFilter全稱是Act

asp.net core 系列12 資料加密演算法

# 0. 前言 這一篇我們將介紹一下.net core 的加密和解密。在Web應用程式中,使用者的密碼會使用MD5值作為密碼資料儲存起來。而在其他的情況下,也會使用加密和解密的功能。 常見的加密演算法分為對稱加密和非對稱加密。所謂的對稱加密是指加密金鑰和解密金鑰是同一個,非對稱加密是值加密金鑰和解密迷藥不

ASP.NET MVC系列淺談MVC

後端 nbsp 文獻 ats 路勁 onf 將在 cot get 描述 本篇文章主要概述ASP.NET MVC,具體包括如下內容: 1.MVC模式概述 2.WebForm概述 3.WebForm與MVC區別 4.ASP.NET MVC發展歷程 5.運用程序結構 6.ASP.

ASP.NET MVC系列淺談表單和HTML輔助方法

繼承 好的 內容 概述 調用 復制 畫圖 models pac 【01】淺談Google Chrome瀏覽器(理論篇) 【02】淺談Google Chrome瀏覽器(操作篇)(上) 【03】淺談Google Chrome瀏覽器(操作篇)(下) 【04】淺談AS

Asp.Net MVC 以小見大一步一步改寫簡單的登入註冊(一)

寫這篇文章其實心裡是比較忐忑的,確實Asp.Net MVC框架出來了很長時間了,我這篇文章稍有過時之嫌。不過本著分享學習的態度,還是寫一寫吧。MVC框架的文章園子裡已經很多了,想專題中的重典、老趙、子秋、老代等人都寫過,我一直想找一個不同的切入點,於是就產生了從一個小例子

ASP.NET Core學習Razor頁面

 這裡介紹了Razor基本用法 建立帶PageModel的Razor 頁面 使用資料庫 展示資料 更新資料 篩選器 準備工作 初始化空的專案(終端輸入:dotnet new web -n=Razor) Nuget新增Microsoft.EntityFrameworkC

ASP.NET Core學習Entity Framework Core

 這裡介紹在ASP.NET Core中使用EF Core,這裡資料庫選的是Sql Server 如何使用Sql Server 新增模型 && 資料庫遷移 查詢資料 儲存資料 如何使用Sql Server  1. 安裝dotnet-ef(已經安裝忽略)

ASP.NET Core學習Web API

 這裡介紹在ASP.NET Core中使用Web API建立 RESTful 服務,本文使用VSCode + NET Core3.0 建立簡單Rest API 格式化輸出 JSON Patch請求 Open API(Swagger)整合 建立簡單Rest API 在終端輸

ASP.NET Core學習遠端過程呼叫 - gRPC使用

 本文介紹在gRPC使用,將從下面幾個方面介紹 什麼是RPC 什麼時候需要RPC 如何使用gRPC 什麼是RPC RPC是Remote Procedure Call簡稱,翻譯過來是遠端過程呼叫。它是一個程序間的通訊技術,基於Client-Server模式,讓程式像呼叫本地方

asp.net core 系列 1 帶你瞭解一下asp.net core

# 0. 前言 這是一個新的系列,名字是《ASP.NET Core 入門到實戰》。這個系列主講ASP.NET Core MVC,輔助一些前端的基礎知識(能用來實現我們需要的即可,並非主講)。同時這個系列也會在後續介紹ASP.NET Core 平臺的其它型別的專案,並帶領大家以各個型別的專案為主要架構開發一個

asp.net core 系列2 控制器與路由的恩怨情仇

0. 前言 在上一篇文章中,我們初步介紹了asp.net core,以及如何建立一個mvc專案。從這一篇開始,我將為大家展示asp.net core 的各種內容,並且嘗試帶領大家來挖掘其中的內在邏輯。 當然,那是以後的事情。這一篇將通過自定義一個控制器來為大家介紹asp.net core mvc 中控制器和路