這篇日誌有點長,收集了一些網上的資源,同志們可以按需要選擇來看。目錄是這樣的:
這個顏色的是笨貓的註釋
·GridView的常用用法總結
·如何獲取 GridView 編輯狀態下單元格里的值
先敘述一下我碰到問題的:
道路表road:roadid,roadname,startjunid,endjunid
路口表junction:junid,junname
startjunid,endjunid存的是int型編號,顯示時要顯示junname路口名字,於是做了一個視圖view_road_junction
現在用一GridView和view_road_junction綁定顯示數據。同時要求能對數據進行修改,變動反應到road表中。
我的做法是:
因爲是視圖,不能直接用GridView自動生成的編輯功能(已經用不同方法嘗試過,不行,偷懶不成功),所以寫了一個OnRowUpdating事件,GridView1_RowUpdating(),在此函數中獲取GridView在編輯狀態下的單元格的值,對road表進行更新操作。點擊頁面上的"編輯"按鈕的時候觸發該事件。
------------------
GridView的常用用法總結
------------------
GridView七種類型字段
Field字段類型 |
說明 |
BoundField(數據綁定字段) |
將Data Source數據源的字段數據以文本方式顯示 |
ButtonField(按鈕字段) |
在數據綁定控件中顯示命令按鈕。根據控件的不同,它可讓您顯示具有自定義按鈕控件(例如【添加】或【移除】按鈕)的數據行或數據列,按下時會引發RowCommand事件 |
CommandField(命令字段) |
顯示含有命令的Button按鈕,包括了Select、Edit、Update、Delete命令按鈕(DetailsView的CommandField才支持Insert命令) |
CheckBoxField(CheckBox字段) |
顯示爲CheckBox類型,通常用於布爾值True/False的顯示 |
HyperLinkField(超鏈接字段) |
將Data Source數據源字段數據顯示成HyperLink超級鏈接,並可指定另外的NavigateUrl超鏈接 |
ImageField(圖像字段) |
在數據綁定控件中顯示圖像字段 |
TemplateField(模板字段) |
顯示用戶自定義的模板內容 |
GridView四種樣式
通過ControlStyle可設置BoundField字段服務器子控件的樣式。
通過FooterStyle可設置BoundField字段之頁尾的樣式。
通過HeaderStyle可設置BoundField字段之頁首的樣式。
通過ItemStyle可設置BoundField字段中數據項的樣式。
格式化字符串
格式代號 |
說 明 |
原始格式 |
格式指令 |
運行結果 |
{0:C} |
顯示貨幣符號格式 |
2005.5 |
{0:C2} |
NT$2,005.50 |
{0:D} |
顯示十進制數格式(限用於整數) |
128 |
{0:D} |
128 |
{0:E} |
顯示科學符號格式 |
2005.5 |
{0:E2} |
2.01E+003 |
{0:F} |
顯示固定小數字數格式 |
2005.5 |
{0:F4} |
2005.5000 |
{0:G} |
顯示一般格式 |
2005.5 |
{0:G} |
2005.5 |
{0:N} |
顯示有逗號固定小數字數格式 |
2005.5 |
{0:N3} |
2,005.500 |
{0:P} |
顯示百分比格式 |
0.25 |
{0:P} |
25.00% |
{0:X} |
顯示十六進制數格式(限用於整數) |
128 |
{0:X} |
80 |
{0:#} |
顯示自定義的數字格式 |
2005.5 |
{0:00####.00} |
002005.00 |
各種類型字段使用方法
BoundField :
HeaderText 列名(在網頁中顯示出來的)
HeaderImageUrl 列頭的圖片
DataField 數據源字段名
NullDisplayText 當該字段的值爲空時顯示的值
ButtonField:
ButtonType 有Button?Image?Link三種
DataTextField 將數據源字段數據綁定到Button按鈕的文本屬性中
ImageUrl 當按鈕形式爲Image時,指定Image所在的Url
CommandName 單擊ButtonField按鈕時所要運行的命令名稱
相關事件:
當ButtonField按鈕字段被按下時,GridView控件會引發RowCommand事件,
若要判斷引發命令事件之數據行的索引,請使用事件自變量的CommandArgument屬性,會將該事件自變量傳遞至數據綁定控件的命令事件,ButtonField類會自動用適當的索引值填入CommandArgument屬性。在事件響應函數中可以根據不同的CommandName來做不同的操作。
從事件中判斷e.CommandName和對第幾行進行的操作e.CommandArgument。
Example:
if (e.CommandName == "Select")
{
int index = Convert.ToInt32(e.CommandArgument);
}
}
CommandField:
五種命令:Select、Edit、Update、Delete與Insert。顯示及隱藏命令按鈕您可以設置ShowDeleteButton、ShowEditButton、ShowInsertButton與ShowSelectButton這幾個屬性(True或False)。而設置不同命令按鈕的文字標題可用的屬性有SelectText、InsertText、UpdateText、DeleteText、CancelText、EditText、NewText。
若您將ButtonType屬性設爲ButtonType.Image,則可以設置按鈕的圖像Url屬性,可供使用的有CancelImageUrl、 DeleteImageUrl、EditImageUrl、InsertText、NewImageUrl、SelectImageUrl、 UpdateImageUrl。
SelectedRowStyle 用於設置選中行的風格
相關事件:
RowEditing
RowDeleting
RowUpdating
RowCancelingEdit
注意:RowEditing和RowUpdating的不同
Example:( 摘自:http://hi.baidu.com/70zz)
後臺代碼:
你可以使用sqlhelper,本文沒用。代碼如下:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
public partial class _Default : System.Web.UI.Page
{
//清清月兒http://blog.csdn.net/21aspnet
SqlConnection sqlcon;
SqlCommand sqlcom;
string strCon = "Data Source=(local);Database=數據庫名;Uid=帳號;Pwd=密碼";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bind();
}
}
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
bind();
}
//刪除
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
string sqlstr = "delete from 表 where id='" + GridView1.DataKeys[e.RowIndex].Value.ToString() + "'";
sqlcon = new SqlConnection(strCon);
sqlcom = new SqlCommand(sqlstr,sqlcon);
sqlcon.Open();
sqlcom.ExecuteNonQuery();
sqlcon.Close();
bind();
}
//更新
//gridview的列、行都是從0開始編號的
//我在用“GridView1.DataKeys[e.RowIndex].Value.ToString()”老是報“索引超出範圍“,不知原因。
//建議改用後文寫的”如何獲取 GridView 編輯狀態下單元格里的值“的方法
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
sqlcon = new SqlConnection(strCon);
string sqlstr = "update 表 set 字段1='"
+ ((TextBox)(GridView1.Rows[e.RowIndex].Cells[1].Controls[0])).Text.ToString().Trim() + "',字段2='"
+ ((TextBox)(GridView1.Rows[e.RowIndex].Cells[2].Controls[0])).Text.ToString().Trim() + "',字段3='"
+ ((TextBox)(GridView1.Rows[e.RowIndex].Cells[3].Controls[0])).Text.ToString().Trim() + "' where id='"
+ GridView1.DataKeys[e.RowIndex].Value.ToString() + "'";
sqlcom=new SqlCommand(sqlstr,sqlcon);
sqlcon.Open();
sqlcom.ExecuteNonQuery();
sqlcon.Close();
GridView1.EditIndex = -1;
bind();
}
//取消
protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
GridView1.EditIndex = -1;
bind();
}
//綁定
public void bind()
{
string sqlstr = "select * from 表";
sqlcon = new SqlConnection(strCon);
SqlDataAdapter myda = new SqlDataAdapter(sqlstr, sqlcon);
DataSet myds = new DataSet();
sqlcon.Open();
myda.Fill(myds, "表");
GridView1.DataSource = myds;
GridView1.DataKeyNames = new string[] { "id" };//主鍵
GridView1.DataBind();
sqlcon.Close();
//若在頁面配置了數據源SqlDataSource1,用下2行代碼,不過在頁面裏不要加SqlDataSourceID=SqlDataSource1屬性了
//GridView1.DataSource = SqlDataSource1;
//GridView1.DataBind();
}
}
前臺主要代碼:
<!--
使用時曾碰到這樣的問題:要激發OnRowUpdating="GridView1_RowUpdating"事件,必須先寫了OnRowEditing="GridView1_RowEditing"事件,不然會報”激發了未處理的事件RowEditing‘“,現在還沒搞清楚什麼原因。。。
--> ... ...
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
ForeColor="#333333" GridLines="None" OnRowDeleting="GridView1_RowDeleting" OnRowEditing="GridView1_RowEditing"
OnRowUpdating="GridView1_RowUpdating" OnRowCancelingEdit="GridView1_RowCancelingEdit">
<FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<Columns>
<asp:BoundField DataField="身份證號碼" HeaderText="用戶ID" ReadOnly="True" />
<asp:BoundField DataField="姓名" HeaderText="用戶姓名" />
<asp:BoundField DataField="員工性別" HeaderText="性別" />
<asp:BoundField DataField="家庭住址" HeaderText="家庭住址" />
<asp:CommandField HeaderText="選擇" ShowSelectButton="True" />
<asp:CommandField HeaderText="編輯" ShowEditButton="True" />
<asp:CommandField HeaderText="刪除" ShowDeleteButton="True" />
</Columns>
<RowStyle ForeColor="#000066" />
<SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
<HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White" />
</asp:GridView>
CheckBoxField:
DataField 設置綁定至數據源的字段名稱
Text 設置CheckBox右側的說明文字
ReadOnly 在編輯模式時,設置ReadOnly屬性可以防止被編輯
HyperLinkField
DataTextField 綁定數據源字段顯示成超鏈接文字
DataNavigateUrlFields 將數據字段綁定到超鏈接字段Url屬性
Target 如果設置爲"_blank"表示在空白頁中打開
ImageField
DataImageUrlField 設置綁定至ImageField對象ImageUrl屬性的數據源字段名稱
TemplateField
ItemTemplate 字段項目模板
AlternatingItemTemplate 字段交替項目模板,若設置這個字段後,奇數行會顯示ItemTemplate,偶數行顯示AlternatingItemTemplate
EditItemTemplate 編輯項目模板
其他常見用法
1 程序中動態設置表頭名稱
gv.Columns[0].HeaderText=”表頭”;
2 修改時獲取文本控件上的文本
string card=((TextBox)CellGrid.Rows[e.RowIndex].Cells[1].Controls[0]).Text;
獲得其他類型的控件同理,將上面代碼的控件類型做修改即可
3 在每一行綁定數據時,會發生RowDataBound事件,可在這裏添加相應的事件響應函數
4 刪除之前提示是否確定刪除:
在RowDataBound事件中加入該代碼
if (e.Row.RowType == DataControlRowType.DataRow)
{
((CheckBox)e.Row.FindControl("CheckBox1")).Attributes.Add("onclick","return confirm('XXX')");
}
5 AutoGenerateColumns 是否自動添加列,如果是的話意味着是通過程序代碼來實現添加的
分頁的實現
關鍵屬性:
AllowPaging設置爲"True"
PageSize設置每一行顯示的行數
Mode 分頁樣式,包含這四種:NextPreviousFirstLast、NumericFirstLast、NextPrevious、Numeric(Numeric指顯示數字;First、Last指最開始和最後一個;Next、Previous指上一個和下一個)
FirstPageImageUrl、LastPageImageUrl、NextPageImageUrl、PreviousPageImageUrl分別指對應的圖片
PagerStyle 中HorizontalAlign、VerticalAlign、BorderStyle用於設置分頁控制的樣式
關鍵事件
OnPageIndexChanging分頁事件
當發生該事件後,重新綁定數據源
Example:
ArticleList.PageIndex = e.NewPageIndex;
if (Session["SQLStr"] != null)
{
string SQLStr = Session["SQLStr"].ToString();
GirdViewRefresh(SQLStr);
}
典型使用步驟:
添加GridView控件,設置相關屬性:
Columns中添加相應的數據行
RowStyle、AlternatingRowStyle設置數據行樣式
分頁設置AllowPaging="True";PageSize設置每頁好顯示的行數
SelectedRowStyle 設置選擇行的樣式
在CS文件添加相應的響應函數:
(1)Page_Load中綁定數據源:
ArticleList.DataSource = ds.Tables[0].DefaultView;
ArticleList.DataBind();
(2)OnPageIndexChanging中更新頁索引,重新綁定數據源
ArticleList.PageIndex = e.NewPageIndex;
if (Session["SQLStr"] != null)
{
string SQLStr = Session["SQLStr"].ToString();
GirdViewRefresh(SQLStr);
}
(3)RowCommand加入事件響應
if (e.CommandName == "Select")
{
int index = Convert.ToInt32(e.CommandArgument);
}
}
----------------------
如何獲取 GridView 編輯狀態下單元格里的值
----------------------
還在使用這樣的代碼嗎?
if (txtName != null)
{
// 讀取值
//
}
其實這些工作(在單元格中查找控件,並嘗試獲取其中的值)已經被封裝了。現在,只要調用 ExtractValuesFromCell 方法即可。
而該方法也被很多種列類型所支持:
DataControlField, BoundField, AutoGeneratedField, CheckBoxField, ImageField, TemplateField, DynamicField
你可以在 GridView 的 RowUpdating, RowDeleting 等事件中使用它。利用該方法,可以將值提取到所需的字典裏去,然後再從字典中讀取。這些字典包括:e.Keys, e.NewValues, e.OldValues 等。
一小段例子代碼:
protected void grid1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
var row = grid1.Rows[e.RowIndex];
// 提取 Id 字段的值
grid1.Columns[0].ExtractValuesFromCell(
e.Keys,
row.Cells[0] as DataControlFieldCell,
DataControlRowState.Edit,
true /* include readonly */);
// 提取 Name 字段的值
grid1.Columns[1].ExtractValuesFromCell(
e.NewValues,
row.Cells[1] as DataControlFieldCell,
DataControlRowState.Edit,
true /* include readonly */);
var id = int.Parse(e.Keys["id"].ToString());
var name = (string) e.NewValues["name"];
// 執行相關的數據庫更新操作
//
}
這樣,在大多數場合我們可以儘可能多的使用 BoundField,並且也能正確讀取到其編輯時的值,省下自定義 TemplateField 的一堆代碼了。