根據上面一篇隨筆所介紹的PC購買流程的項目,在項目中,需要有一個生成 訂單的功能,能夠使得Admin很方便的在獲得批准的申請中選取一些來生成訂單 ,要求界面操作簡單明了,大概的效果圖如下:
點擊checkbox,自動計算當前訂單的總價值,點擊按鈕,生成訂單。
有此想到了用SPGridView這個現成的控件來完成,以前也用過這個控件,其 實和GridView沒什麼大區別。這裡就簡單介紹一下了:
首先Create 一個WebPart
在CreateChildControls()中可以設置SPGridView 的數據源和屬性,添加 Field等等。
但是CheckBox這一列,必須自己自定義一個模板類來生成,下面是我們自定 義的CheckBox模板類,它實現了ITemplate接口:
class CheckBoxTemplateField:ITemplate
{
string id;
public EventHandler OnCheck = null;
public CheckBoxTemplateField(string chbId, EventHandler checkEvent)
{
id = chbId;
OnCheck = checkEvent;
}
public void InstantiateIn(System.Web.UI.Control container)
{
CheckBox chb = new CheckBox();
chb.AutoPostBack = true;
chb.ID = id;
chb.CheckedChanged += OnCheck;
container.Controls.Add(chb);
}
}
這樣就可以在SPGridView中調用這個模板類,並且為Oncheck事件提供處理方 法:
protected override void CreateChildControls()
{
if (!_error)
{
try
{
SPList sourceList = SPContext.Current.Web.Lists["Purchase Request"];
dataSource = new SPDataSource();
this.Controls.Add (dataSource);
dataSource.List = sourceList;
gridView = new SPGridView();
gridView.AutoGenerateColumns = false;
TemplateField chbField = new TemplateField();
chbField.HeaderText = "";
EventHandler onCheck = new EventHandler(OnCheck);
chbField.ItemTemplate = new CheckBoxTemplateField("chb", onCheck);
gridView.Columns.Add (chbField);
當我們提供了所以的Field綁定後,需要指定一列為Group列,我們這裡指定 了"Team"列:
SPBoundField createdField = CreateNewBoundField("Created", "Created", 0);
gridView.Columns.Add (createdField);
SPBoundField applicantField = CreateNewBoundField("Created By", "Created By", 0);
gridView.Columns.Add (applicantField);
SPBoundField mtField = CreateNewBoundField("Machine Type", "Machine Type", 0);
gridView.Columns.Add (mtField);
SPBoundField compField = CreateNewBoundField("Component Type", "Component Type", 0);
gridView.Columns.Add (compField);
SPBoundField purNumField = CreateNewBoundField("Purchase Number", "Purchase Number", 0);
gridView.Columns.Add (purNumField);
SPBoundField purReasonField = CreateNewBoundField("Purchase Reason", "Purchase Reason", 0);
gridView.Columns.Add (purReasonField);
SPBoundField mgrAppField = CreateNewBoundField("Manager Approval", "Manager Approval", 0);
gridView.Columns.Add (mgrAppField);
SPBoundField drtAppField = CreateNewBoundField("Director Approval", "Director Approval", 0);
gridView.Columns.Add (drtAppField);
SPBoundField priceField = CreateNewBoundField("Total Price", "Total Price", 0);
gridView.Columns.Add (priceField);
gridView.AllowGrouping = true;
gridView.AllowGroupCollapse = true;
gridView.GroupField = "Team";
gridView.GroupFieldDisplayName = "Team";
但是"Team"這個Field在數據源的List中是Lookup類型的,如果不作處理,那 麼顯示的結果將會是 Team:23;#SharePoint Test,即 連lookupid也顯示出來了 ,這裡我們需要在數據綁定的時候作處理,為此我們添加了 gridView.RowDataBound += new GridViewRowEventHandler (gridView_RowDataBound)這個事件,gridView_RowDataBound 的代碼如下:
void gridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((sender as SPGridView).AllowGrouping)
{
SPGridViewRow gridViewRow = e.Row as SPGridViewRow;
if (gridViewRow != null && gridViewRow.HeaderText != null)
{
gridViewRow.HeaderText = "Team : " + new SPFieldLookupValue (DataBinder.GetPropertyValue(e.Row.DataItem, (sender as SPGridView).GroupField).ToString()).LookupValue;
}
}
}
}
這樣,確保我們在SPGridView中做Groupby時,顯示的只是LookupValue,而 非LookupId;#LookUpValue的形式。
另外我們可以通過設置SPGridView的DataKeyNames為各行保存一些我們可能 需要的信息,例如
gridView.DataKeyNames = new string[] { "ID", "Team", "Created By", "Total Price", "Machine Type", "Component Type", "Purchase Number", "Shipped Order" };
如下就可以使用這些數據:
gridView.DataKeys[row.RowIndex].Values["Machine Type"].ToString ();
我們用SPGridView作為WebPart開發的時候還遇到了一個問題,就是一訪問 SharePoint的Session,頁面就報異常。但是在代碼中,並為出現異常,檢查了 Web.config文件,發現HttpModule中也加了Session Module,<Page>節點 中也Enable了Session, 至今未能找出原因,後來不得已,用了Context.Cache來 代替,希望各位看官,有知道原因的,還請不吝賜教。謝謝拉~
SPGridView使用不復雜,關鍵還在於理清楚項目中的業務邏輯,選擇合適的 Solution來解決問題。