讓DataGrid擁有單擊回傳事件並帶回指定欄位的值
來源:互聯網
上載者:User
datagrid 讓DataGrid擁有單擊回傳事件並帶回指定欄位的值
在遇到主從表結構的時候,我們經常會有這樣的需求
那就是用一個DataGrid來列出主表的資訊,然後選中主表中的一條記錄根據主外健的值讓另外一個DataGrid來顯示從表的資訊。但是在DataGrid的事件中滿足不了我們的需求,我們需要給DataGrid添加一個OnSelectPostBack事件,那麼我們每選中一條主表記錄就會引發一次回傳,在事件裡我們取到指定的資料來源的指定欄位的值,綁定從表的資訊
讓我們給我們得擴充DataGrid取個很牛的開發代號:SelectPostBackDataGrid
大體上我們需要擴充的內容有:
1、 事件
public delegate void SelectPostBackEventHandler(object sender, SelectPostBackEventArgs e);
public event SelectPostBackEventHandler OnSelectPostBack;
因為我們要傳回參數,所以要自訂自己的委託事件,以便通過事件參數傳回我們指定欄位的值
自訂事件參數,我們需要行所引和傳回的欄位值就可以了,當然你喜歡什麼就傳回什麼,只要你樂意。
public class SelectPostBackEventArgs : EventArgs
{
private string n_Value;
private int index;
internal SelectPostBackEventArgs(int index, string Value)
{
this.index = index;
this.n_Value = Value;
}
public string Value
{
get { return n_Value; }
}
public int Index
{
get { return index; }
}
}
2、 要傳回的資料來源欄位
public string SelectPostBackDataField
{
get
{
if (ViewState[base.UniqueID + "SelectPostBackDataField"] == null)
return null;
return ViewState[base.UniqueID + "SelectPostBackDataField"].ToString();
}
set { ViewState[base.UniqueID + "SelectPostBackDataField"] = value; }
}
public bool AllowSelectPostBack
{
get
{
if (ViewState[base.UniqueID + "AllowSelectPostBack"] == null)
return true;
return bool.Parse(ViewState[base.UniqueID + "AllowSelectPostBack"].ToString());
}
set { ViewState[base.UniqueID + "AllowSelectPostBack"] = value; }
}
我們多個屬性AllowSelectPostBack來設定需不需要回傳,或許把握們的這個擴充的DataGrid當普通DataGrid來用以未嘗不可阿!當然亦可以判斷有沒有事件在決定回不回傳也是不錯的。
之所以要儲存到檢視狀態裡面去,這是眾所周知的緣故我這裡就不用多說了!
3、 讓DataGrid擁有單擊回傳事件
似乎是一件非常奇妙的事情,讓我們來看看DataGrid的在頁面結構
在頁面上一個<TR></TR>對應的就是以行,那麼添加單擊事件就是給<TR>添加onclick事件就可以了,或者添加雙擊事件,哈哈!只要你喜歡。而<TR>對應DataGrid背景對象就是一個Item,那麼這個Item就是DataGrid的一行了,根據DataGrid初始化Item的順序,首先是頭,然後是身體,再就是角。哈哈!就是從上到下啦。因此Item也有好幾種類型,我們只需要給資料行添加單擊事件就行了,別的都不需要管,也就是給Item的ItemType是Item,AlternatingItem,SelectedItem的行添加單擊事件就可以了
當然我們就在初始化行的時候做上面的事情,因此在建構函式裡我們加上初始化行的事件,然後再我們的事件函數裡面幹上面的活,注意一點是,我們要取到每一行我們指定要回傳的欄位的值
DataBinder.Eval(e.Item.DataItem, SelectPostBackDataField).ToString()
這個方法取到指定欄位在該行的值(這個方法在2.0中得到加強,非常好)
那麼在單擊事件的回傳參數中我們就可以把這個之傳回來
建構函式裡發生的事情和事件函數內要做的工作如下:
public SelectPostBackDataGrid()
{
base.ItemDataBound += new DataGridItemEventHandler(SelectPostBackDataGrid_ItemDataBound);
}
private void SelectPostBackDataGrid_ItemDataBound(object sender, DataGridItemEventArgs e)
{
if (!AllowSelectPostBack)
return;
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.SelectedItem)
{
string argstring = e.Item.ItemIndex.ToString();
if (SelectPostBackDataField != null)
argstring += "_" + DataBinder.Eval(e.Item.DataItem, SelectPostBackDataField).ToString();
e.Item.Attributes.Add("onclick", Page.GetPostBackEventReference(this, argstring));
}
}
單擊事件終究還是放生了!哈哈!
那麼從頁面傳回來的參數我們怎麼接受呢?這裡需要嚴重注意的一點就是想要取到傳回來的參數,最聰明方法就是實現IPostBackEventHandler介面,當然你也可以喜歡用別的辦法,可能你需要傳回來個多個複雜的資料,只要你夠聰明,什麼資料都可以穿來穿去,網路的力量就是厲害,nero就是偉大的,我們也很偉大,因為我們有IPostBackEventHandler介面,就像是時空隧道一樣,不需要任何多餘的東西。(哈哈!越扯越遠了)
實現這個介面之
public virtual void RaisePostBackEvent(string eventArgument)
{
int index;
string fieldvalue = null;
if (SelectPostBackDataField != null)
{
index = int.Parse(eventArgument.Substring(0, eventArgument.IndexOf('_')));
int beginindex = eventArgument.IndexOf('_') + 1;
int leng = eventArgument.Length - eventArgument.IndexOf('_') - 1;
fieldvalue = eventArgument.Substring(beginindex, leng);
}
else
index = int.Parse(eventArgument);
this.SelectedIndex = index;
if (OnSelectPostBack != null)
{
OnSelectPostBack(this, new SelectPostBackEventArgs(index, fieldvalue));
}
}
這裡面做的事情就是把頁面傳回來的參數處理一下,執行個體化我們的自訂事件參數,然後引發我們的事件,事情就結束了。當然,在用這個組件是添加的事件也就被引發了,也就取到我們自訂參數中的值了。
簡單的就是實現了單擊回傳的事件,當然可以幹很多你喜歡乾的事情,這裡只是個樣本
下面是完整的代碼,只要拷貝拿去編譯就可以了哦!
如果你喜歡,希望是 GPL 的支援者,為技術獻身
using System;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.ComponentModel;
namespace hl
{
public class SelectPostBackDataGrid : DataGrid, IPostBackEventHandler
{
public SelectPostBackDataGrid()
{
base.ItemDataBound += new DataGridItemEventHandler(SelectPostBackDataGrid_ItemDataBound);
}
public delegate void SelectPostBackEventHandler(object sender, SelectPostBackEventArgs e);
public event SelectPostBackEventHandler OnSelectPostBack;
public virtual void RaisePostBackEvent(string eventArgument)
{
int index;
string fieldvalue = null;
if (SelectPostBackDataField != null)
{
index = int.Parse(eventArgument.Substring(0, eventArgument.IndexOf('_')));
int beginindex = eventArgument.IndexOf('_') + 1;
int leng = eventArgument.Length - eventArgument.IndexOf('_') - 1;
fieldvalue = eventArgument.Substring(beginindex, leng);
}
else
index = int.Parse(eventArgument);
this.SelectedIndex = index;
if (OnSelectPostBack != null)
{
OnSelectPostBack(this, new SelectPostBackEventArgs(index, fieldvalue));
}
}
//Attribute
public string SelectPostBackDataField
{
get
{
if (ViewState[base.UniqueID + "SelectPostBackDataField"] == null)
return null;
return ViewState[base.UniqueID + "SelectPostBackDataField"].ToString();
}
set { ViewState[base.UniqueID + "SelectPostBackDataField"] = value; }
}
public bool AllowSelectPostBack
{
get
{
if (ViewState[base.UniqueID + "AllowSelectPostBack"] == null)
return true;
return bool.Parse(ViewState[base.UniqueID + "AllowSelectPostBack"].ToString());
}
set { ViewState[base.UniqueID + "AllowSelectPostBack"] = value; }
}
//private method
private void SelectPostBackDataGrid_ItemDataBound(object sender, DataGridItemEventArgs e)
{
if (!AllowSelectPostBack)
return;
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.SelectedItem)
{
string argstring = e.Item.ItemIndex.ToString();
if (SelectPostBackDataField != null)
argstring += "_" + DataBinder.Eval(e.Item.DataItem, SelectPostBackDataField).ToString();
e.Item.Attributes.Add("onclick", Page.GetPostBackEventReference(this, argstring));
}
}
}
public class SelectPostBackEventArgs : EventArgs
{
private string n_Value;
private int index;
internal SelectPostBackEventArgs(int index, string Value)
{
this.index = index;
this.n_Value = Value;
}
public string Value
{
get { return n_Value; }
}
public int Index
{
get { return index; }
}
}
}