昨天看到一行 Import static java.xxx.xx;
google 一下知道, 原來對於程式中使用到某類別的static member
可以透過import達到不需要這樣: class_name.static_member
語法>>
import class's single static member
import static java.lang.Math.PI;
或import class's all static members
import static java.lang.Math.*;
不過import static也不要用太多, 以免降低程式碼的可閱讀性
2010年12月26日 星期日
2009年4月8日 星期三
2009年4月6日 星期一
在GridView內實現編輯、刪除
如果要在GridView內做到編輯或刪除的動作
有兩種作法:
(1)加入CommandField
(2)加入TemplateField
重點:從一般模式進入Edit要指定EditIndex,而且要執行DataBind()才會進入編輯模式(顯示TextBox)!!如果是用後端餵DataSource的方式,要記得再餵一次!!!
作法大致如下:
(1)加入CommandField
後端要處理GridView的RowEditing、RowCancelingEdit、RowDeleting、RowUpdating等事件
例如:
(2)加入TemplateField
CommandName目的是為了待會處理RowCommand事件時辨別是Edit、Delete or Cancel
CommandArgument則是為了要知道哪列資料要修改或刪除
後端程式碼則只要處理RowCommand事件
如下:
事實上,
方法(1)使用CommandField也是會觸發RowCommand事件
只不過我們忽略他而已
而且RowCommand事件會比RowEditing、RowCancelingEdit..等事件先被觸發!
有兩種作法:
(1)加入CommandField
(2)加入TemplateField
重點:從一般模式進入Edit要指定EditIndex,而且要執行DataBind()才會進入編輯模式(顯示TextBox)!!如果是用後端餵DataSource的方式,要記得再餵一次!!!
作法大致如下:
(1)加入CommandField
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:CommandField ShowEditButton="True" ShowDeleteButton="True"/>
<asp:BoundField DataField="ProgramName" HeaderText="ProgramName"/>
<asp:BoundField DataField="iconid" HeaderText="iconid"/>
<asp:BoundField DataField="classid" HeaderText="classid"/>
</Columns>
</asp:GridView>
後端要處理GridView的RowEditing、RowCancelingEdit、RowDeleting、RowUpdating等事件
例如:
Protected Sub GridView1_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles GridView1.RowEditing
'指定哪列資料進入EditMode
Me.GridView1.EditIndex = e.NewEditIndex
'宣告一個執行Query DB的 object(自訂class)
Dim DataObjUtil As New DataObjectUtility()
Me.GridView1.DataSource = DataObjUtil.GetDataTable("select programname,iconid,classid from tb_functionmenu", Me.Page)
'完成Bind才會讓該列進入EditMode!
Me.GridView1.DataBind()
End Sub
(2)加入TemplateField
<asp:GridView ID="GrvSPCKC" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:Button ID="BtnUpdate" runat="server" Text="更新" CommandName="UpdateRow" CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>" />
<asp:Button ID="BtnCancel" runat="server" Text="取消" CommandName="CancelRow" CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>" OnClientClick="return confirm('確定放棄編輯?');" />
</EditItemTemplate>
<ItemTemplate>
<asp:Button ID="BtnEdit" runat="server" Text="修改" CommandName="EditRow" CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>" />
<asp:Button ID="BtnDel" runat="server" Text="刪除" CommandName="DelRow" CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>" OnClientClick="return confirm('確定刪除?');" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="DFCD" DataField="dfcd" />
<asp:BoundField HeaderText="RVNO" DataField="rvno" />
</Columns>
</asp:GridView>
CommandName目的是為了待會處理RowCommand事件時辨別是Edit、Delete or Cancel
CommandArgument則是為了要知道哪列資料要修改或刪除
後端程式碼則只要處理RowCommand事件
如下:
Protected Sub GrvSPCKC_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GrvSPCKC.RowCommand
'讀取傳入的列編號
Dim TrigerRowIndex As Integer = Convert.ToInt32(e.CommandArgument)
'根據CommandName參數呼叫各別函式處理
Select Case e.CommandName
Case "EditRow"
Me.ChangeToEditMode(TrigerRowIndex)
Case "CancelRow"
Me.CancelEditRow()
Case "DelRow"
Me.DeleteRow(TrigerRowIndex)
Case "UpdateRow"
Me.UpdateRow(TrigerRowIndex)
End Select
End Sub
事實上,
方法(1)使用CommandField也是會觸發RowCommand事件
只不過我們忽略他而已
而且RowCommand事件會比RowEditing、RowCancelingEdit..等事件先被觸發!
2009年3月31日 星期二
以程式方式加入網頁Head
//My first CSS
HtmlLink myCSS = new HtmlLink();
myCSS.Href = "~/somecss1.css";
myCSS.Attributes.Add("rel", "stylesheet");
myCSS.Attributes.Add("type", "text/css");
Page.Header.Controls.Add(myCSS);
//Here comes my second
myCSS = new HtmlLink();
myCSS.Href = "~/somecss2.css";
myCSS.Attributes.Add("rel", "stylesheet");
myCSS.Attributes.Add("type", "text/css");
Page.Header.Controls.Add(myCSS);
//JavaScript!
HtmlGenericControl myJavaScript = new HtmlGenericControl();
myJavaScript.TagName = "script";
myJavaScript.Attributes.Add("type", "text/javascript");
myJavaScript.InnerText = "alert('Hello');";
Page.Header.Controls.Add(myJavaScript);
//view source code
<link href="somecss1.css" rel="stylesheet" type="text/css" /><link href="somecss2.css" rel="stylesheet" type="text/css" /><script type="text/javascript">alert('Hello');</script>
缺點就是原始碼會串成一大串,很醜
如果在每個header元素加入這行:
Page.Header.Controls.Add(new LiteralControl("\r\n"));
這樣source code就會變的美美地:
<link href="somecss1.css" rel="stylesheet" type="text/css" />
<link href="somecss2.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
alert('Hello');
</script>
2009年3月3日 星期二
C++ list sort (以結構的子成員排序)
在「C++標準函式庫」一書中提到,
排序演算法中 sort 不適用於list,因為list不支援隨機存取 iterator,
但 list 提供了一個成員函式 sort( ),預設是以 operator < 對所有元素排列。
list.sort( ) 是以 operator < 為準則,對所有元素排列,
但此功能僅限於 list 所存放的是可比較的單純數值型別,
如果在 list 中所存放的是 programmer 自行定義的結構(如含有 id 與姓名),
則無法使用此函式去排序,
比較好的解法是重載 operator (此方法可用於 class 中),
如此一來便可以 list 中的結構子成員來排序,
另一方法,只可使用於較單純的程式裡,因為不能用在class中,
加入 code 已被覆蓋,所以還是用上面的方法吧:)
排序演算法中 sort 不適用於list,因為list不支援隨機存取 iterator,
但 list 提供了一個成員函式 sort( ),預設是以 operator < 對所有元素排列。
list.sort( ) 是以 operator < 為準則,對所有元素排列,
但此功能僅限於 list 所存放的是可比較的單純數值型別,
如果在 list 中所存放的是 programmer 自行定義的結構(如含有 id 與姓名),
則無法使用此函式去排序,
比較好的解法是重載 operator (此方法可用於 class 中),
如此一來便可以 list 中的結構子成員來排序,
#include
#include
using namespace std;
typedef struct data
{
data(int i, string s)
{
id = i;
str = s;
}
bool operator>(const data &data2) const
{
return (id < data2.id);
}
int id;
string str;
} DATA_T;
listd_list;
int main()
{
d_list.push_back(DATA_T(8, string("q1")));
d_list.push_back(DATA_T(2, string("q2")));
d_list.push_back(DATA_T(3, string("q3")));
cout << "Before sort:" << endl;
for(list::iterator iter = d_list.begin(); iter != d_list.end(); ++iter) {
cout << (*iter).id << " " << (*iter).str << endl;
}
d_list.sort(greater());
cout << "After sort:" << endl;
for(list::iterator iter = d_list.begin(); iter != d_list.end(); ++iter) {
cout << (*iter).id << " " << (*iter).str << endl;
}
return 0;
}
另一方法,只可使用於較單純的程式裡,因為不能用在class中,
加入 code 已被覆蓋,所以還是用上面的方法吧:)
2009年2月24日 星期二
Include external Jascript file and CSS style sheet
Include 外部 Javascript檔
重點: (1)script標籤要有close tag!
(2)使用"src"屬性而"非href"!!!
<script type="text/javascript" src="../Script/TreeView.js"></script>
InInclude 外部 CSS檔
重點: (1)link標籤不需close tag!
(2)使用"href"屬性!!!
<link rel=stylesheet type="text/css" href="../CssStyle/UserControl.css"/>
標籤:
CSS,
Javascript,
WebForm
2009年2月21日 星期六
為報表加入參數時的注意事項
一般來說
報表的參數通常用在報表在過濾資料或者查詢資料時
也就是我們把Query database與bind通通交給Crystal Report做
但是如果我們是利用程式手動餵DataTable給ReportDocument
再把這個ReportDocument指為CrystalReportViewer的ReportSource
參數還是可以具體的以"參數欄位"show值在報表上
例如:產生週、月、季報表時,除了基本的報表日期,
我們可以將user前一個步驟給定的週、月、季或年呈現在報表
讓閱讀報表時更明白資料內容。
指定報表參數三步驟
(1)在報表設計(.rpt)建立參數欄位,並拉至報表畫面中

(2)在負責產生報表內容的class檔中,建立一個function設定報表參數,例如:
(3)在設定CrystalReportViewer.ReportSource後執行步驟(2)的function

不過,經過測試後
反而是先指定指定ReportSource屬性再指定ParameterFieldInfo才不會出錯!!!
Ok,如果是WindowForm到這一步已經大功告成了
但是如果你像我一樣是寫web專案
你會發現操作CrystalReportViewer上的tool bar時報表內容會消失
顯然這與web先天無狀態有關
要處理這個問題只好把session搬出來了
我的作法是在設定CrystalReportViewer.ReportSource時
將ReportDocument的資料(DataTable)寫入Session:
本來想直接把ReportDocument物件寫入session
省掉Load、SetDataSource步驟,可惜失敗...只好用2個session分別記錄DataTable與rpt檔名
然後在page事件中再餵一次報表資料:
這裡有個小訣竅
千萬不要寫在PageLoad事件中
否則執行時會有意想不到的結果產生
(我的情況是換頁時頁碼會亂跳!!)
報表的參數通常用在報表在過濾資料或者查詢資料時
也就是我們把Query database與bind通通交給Crystal Report做
但是如果我們是利用程式手動餵DataTable給ReportDocument
再把這個ReportDocument指為CrystalReportViewer的ReportSource
參數還是可以具體的以"參數欄位"show值在報表上
例如:產生週、月、季報表時,除了基本的報表日期,
我們可以將user前一個步驟給定的週、月、季或年呈現在報表
讓閱讀報表時更明白資料內容。
指定報表參數三步驟
(1)在報表設計(.rpt)建立參數欄位,並拉至報表畫面中

(2)在負責產生報表內容的class檔中,建立一個function設定報表參數,例如:
'paramName=報表參數名稱,與rpt檔中的"參數欄位"相同
'paramValue=報表參數值
Public Sub AddParameter(ByVal paramName As String, ByVal paramValue As String)
Dim ParamField As New ParameterField()
Dim ParamDiscreteValue As New ParameterDiscreteValue()
Dim ParamFields As New ParameterFields()
ParamField.ParameterFieldName = paramName
ParamDiscreteValue.Value = paramValue
ParamField.CurrentValues.Add(ParamDiscreteValue)
ParamFields.Add(ParamField)
'把Show報表的CrystalReportViewer物件的ParameterFieldInfo屬性指定為
'剛建立的ParameterFields物件
Me.RptViewer.ParameterFieldInfo = ParamFields
'release resource
ParamField = Nothing
ParamFields = Nothing
ParamDiscreteValue = Nothing
End Sub
簡單來說報表參數的架構是:
ParameterFields集合物件下包含多個ParameterField
一個ParameterField的CurrentValues屬性(Class ParameterValues)
又是集合多個ParameterValue物件....
(上面我以ParameterDiscreteValue物件表示,因為ParameterValue有兩個子類別:
ParameterDiscreteValue與ParameterRangeValue。)
感覺設定ParameterValue有點麻煩
有ParameterFields、ParameterField
又有ParameterValues、ParameterValue
可以理解報表參數可能不只一個,但是為何Value也要用個集合來放??
用MSDN的例子說明:
假若銷售統計報表有"City"這個參數
想要知道Taipei、Kaohsiung這兩個city的銷售情況時
就可以分別指定兩個ParameterValue物件的Value為Taipei、Kaohsiung.....right?
因為報表參數的設計理念是透過報表執行查詢與過濾資料
如果只是單純呈現參數欄位是比較看不出它的作用的
(3)在設定CrystalReportViewer.ReportSource後執行步驟(2)的function
雖然,根據MSDN說明,在指定ReportSource屬性前要先指定ParameterFieldInfo,
否則會出現要求輸入參數值的畫面。例如:

不過,經過測試後
反而是先指定指定ReportSource屬性再指定ParameterFieldInfo才不會出錯!!!
Ok,如果是WindowForm到這一步已經大功告成了
但是如果你像我一樣是寫web專案
你會發現操作CrystalReportViewer上的tool bar時報表內容會消失
顯然這與web先天無狀態有關
要處理這個問題只好把session搬出來了
我的作法是在設定CrystalReportViewer.ReportSource時
將ReportDocument的資料(DataTable)寫入Session:
Public Sub ConfigReport(ByVal paramRptFileName As String, ByVal paramRptData As DataTable)
Me._ReportDocument = New ReportDocument()
Session("RptFileName") = Me.GetReportPhysicPath(paramRptFileName)
Me._ReportDocument.Load(Session("RptFileName"))
Me._ReportDocument.SetDataSource(paramRptData)
Me.RptViewer.ReportSource = Me._ReportDocument
Me.RptViewer.DataBind()
Session("ReportData") = paramRptData
End Sub
本來想直接把ReportDocument物件寫入session
省掉Load、SetDataSource步驟,可惜失敗...只好用2個session分別記錄DataTable與rpt檔名
然後在page事件中再餵一次報表資料:
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
If IsPostBack Then
If Session("ReportData") IsNot Nothing Then
Me._ReportDocument = New ReportDocument()
Me._ReportDocument.Load(Session("RptFileName"))
Me._ReportDocument.SetDataSource(Session("ReportData"))
Me.RptViewer.ReportSource = Me._ReportDocument
Me.RptViewer.DataBind()
Else
RaiseEvent ReportSessionTimeOut()
End If
End If
End Sub
這裡有個小訣竅
千萬不要寫在PageLoad事件中
否則執行時會有意想不到的結果產生
(我的情況是換頁時頁碼會亂跳!!)
標籤:
CrystalReport,
WebForm,
WindowForm
訂閱:
文章 (Atom)