2012年6月7日 星期四

C# 存取修飾詞 public, protected, private, internal, protected internal 的區別


public
型別或成員可由相同組件或參考該組件的另一個組件中的任何其他程式碼存取。
protected
型別或成員只能由相同類別或結構中,或是衍生類別中的程式碼存取
private
型別或成員只能由相同類別或結構中的程式碼存取。
internal
型別或成員可由相同組件中的任何程式碼存取,但是不包括其他組件中的程式碼。
protected internal
型別或成員可由相同組件中的任何程式碼,或是其他組件中的任何衍生類別存取。



節錄自:

2012年6月1日 星期五

C# 繼承


要 C# 中做到跟 Delphi 以下 inherited 一樣效果,C#作法測試說明:

type
  TfrmPrnSuCount1 = class(TfrmPrnList)
:
:
procedure TfrmPrnSuCount1.QuickRep1BeforePrint(Sender: TCustomQuickRep;
  var PrintReport: Boolean);
begin
  //此指令,會呼叫 基底Form 
  //frmPrnList.QuickRep1BeforePrint()執行後
  //再回來往下執行
  inherited; 

  case g_iMode of
    0:  //全部列印
    begin
      QRLabel5.Caption:= '列印範圍:全部列印';
    end;
    1:  //日期範圍
    begin
      QRLabel5.Caption:= 
        '列印範圍:'+ 
        C_StoC(g_sBdate)+ '~'+ 
        C_StoC(g_sEdate);
    end;
  end;
end;


------------------------------
使用了 Virtual 配合 Override 的變通應用


namespace GISTools
{
    //基底Form frmAsk
    public partial class frmAsk : Form
    {
        public frmAsk()
        {
            InitializeComponent();
        }


        //確定按鈕
        public virtual void btnOk_Click(object sender, EventArgs e)
        {
            //btnOk.DialogResult = DialogResult.OK;
            MessageBox.Show("ASK 基底Form!!");
        }
    }
:
:
    //繼承Form frmM301, 繼承自frmAsk
    public partial class frmM301 : GISTools.frmAsk
    {
        public frmM301()
        {
            InitializeComponent();
        }


        //確定按鈕
        //三種不同結果測試
        //第一種:只會秀"ASK 基底Form!!"
        //new public void btnOk_Click(object sender, EventArgs e)
        //{
        //    MessageBox.Show("M301 World!!");
        //}




        //第二種:只會秀"M301 World!!"
        //public override void btnOk_Click(object sender, EventArgs e)
        //{
        //    MessageBox.Show("M301 World!!");
        //}




        //第三種:會先秀"ASK 基底Form!!",
        //      再秀 "M301 繼承Form!!"
        public override void btnOk_Click(object sender, EventArgs e)
        {
            //因為基底frmAsk.btnOk_Click()用了Virtual, 
            //無法再用static, 故要先把物件實體化才能用
            frmAsk frmAsk1 = new frmAsk();  
            frmAsk1.btnOk_Click(sender, e);
            frmAsk1.Dispose();


            MessageBox.Show("M301 繼承Form!!");
        }
    }
}

---
Welly

2012年5月12日 星期六

.NET使用NPOI Library開發Server端不須安裝Office但能存取Office檔案程式


在 Server 端存取 Excel 檔案的利器:NPOI Library



Codeplex 軟體套件(Package)資訊
套件名稱NPOI
作者tonyqus, huseyin, atao
目前版本1.2.1 Stable(正式版)
URLhttp://npoi.codeplex.com/
使用難易度
使用此套件時可用的輔助工具Visual Studio 2008
POIFS Browser 1.2
基礎知識基本物件導向。
Excel 基礎操作。

在 Server 端控制 Excel 的難處

在今日 Microsoft Excel 被廣為業界接受之際,Excel 已幾乎是每個人必會的工具,不論是在校園或是職場,接觸到 Excel 的機率很高,而且 Excel 靠著簡單易用以及高度容錯的能力,讓使用者可以近乎無痛的操控 Excel,它內建的強大試算以及資料整理的功能,也讓很多使用者樂於使用它,這一點由 Excel 的高市佔率得以印證,用 Excel 來整理與包裝資料已經是司空見慣的事,因此很多的使用者會利用它來處理日常的業務資料或是基本檔等等,不過這可就苦了 IT 人員了。
在論壇上經常會看到一種需求,因為使用者不論如何都要用 Excel 檔來放資料,所以總是要求 IT 人員在系統中直接產出 Excel 檔案直接下載給使用者,目前由官方公布,由伺服器端存取 Excel 表格兩種方法:

2012年4月19日 星期四

看完這篇文章,也許對人生想法會不一樣...


看完這篇文章,
也許對人生想法會不一樣......



記得小時候,我很憧憬長大。

因為我覺得等長大了,父母就再也管不著我了。

可以想喝汽水就喝汽水,

中午想不睡覺就不睡覺,那一定很幸福。

等我真的長大,父母也的確管不著了,

可是當初認為的幸福並沒有到來。

因為,雖然沒有人再管我喝汽水,

但我發現當初那個理想太微不足道。

而且,在得到這個微不足道的自由的同時,

又有了新的更大的不自由。

比如說:八點上班,

哪怕遲到5分鐘,老闆也要給臉色看。

而且那個臉色,比小時候父母的難看得多。

於是,我反而開始懷念

小時候那無憂無慮的生活,

覺得那似乎才是幸福。

同時,又開始了新的憧憬:

什麼時候才能實行彈性的工時,

那一定是很幸福的,

可以想睡到幾點就睡到幾點,

再不用被鬧鈴驚醒好夢,

再不用連臉都不洗、牙沒刷,

就往辦公室狂奔。

若干年後,終於實現了彈性的工時。

不僅如此,隨著自己混成資深人員,

可以想幾點上班就幾點上班,
哪怕在家辦公也沒人說你。



可是我發現,

當初期望的幸福又跑得無影無蹤。

因為,隨著年齡的增長,

沒有鬧鈴,早上也沒了睡懶覺的福氣。
甚至天不亮就醒來,

無所事事的瞪眼到天明。

雖然沒人再要求你,

可是按時起床、工作卻成了習慣,

彈性工時與幸福哪有什麼關係!

回憶幾十年的工作經歷,

我還發現,每換到另一個單位時,

都會有一個感覺令人討厭的主管,
往往都會找我的麻煩。



於是,每每總是希望這個主管調走,
並固執地認為:只要這個人調走,

工作就會很開心。

有幾次,他不走我走,

此處不留爺,自有留爺處。

可是,每一次都會發現,無論到哪,

各形各色的和我作對的主管都如影隨形。

於是又開始憧憬:哪天媳婦熬成了婆,

到我能說了算,不用再受主管的氣,

那一定很幸福。

若干年後,終於熬出了頭:

自己當上高級主管,可以頤指氣使,

讓別人看我的臉色了。

可是我發現,當初渴望的幸福還是沒有來。

因為,雖然沒有人再對你說三道四,
但是,怎麼什麼責任都要我負,

大事小情都要我拍板,心怎麼這麼累呢?

而且,周邊的人怎麼都變得如此虛偽,

自己放個屁,別人都會說香。

於是,天天開會、應酬、聽彙報、佈置工作,

忙得像個陀螺一樣的我,又開始新的憧憬:
哪天能夠活得悠哉遊哉,

不用再管那麼多事,

想釣魚就釣魚,想打牌就打牌,

不 用再看那麼多虛偽的面孔、

聽那些肉麻的假話、看那些枯燥的檔案,

那才是幸福。

光陰似箭,轉眼退休了,

真的再沒有人要我負任何責任,

當初煩人的電話也不再打來,
門庭也真的冷落到鞍馬稀,

所有時間都屬於了自己,

我卻發現,當初渴望的幸福,

哪裡是什麼幸福?

簡直就是人走茶涼的冷落和無盡的孤獨。

於是,一個人坐在殘陽下,

開始思考人生:

我這一生,從小到大,從大到老,
都覺得如果怎樣,明天就會得到幸福,

可為為何在一個個願望實現後,

幸福依舊沒有來?

這時候,才算真正明白了一句話:



“過去心不可得,未來心不可得。”

一切其實盡在當下。

如果你覺得現在不幸福,

總覺得改變了才是幸福,

或者過去了的才是幸福,
那麼恐怕一輩子都難有真正的幸福感!

不是嗎?未來的還沒有來,過去的已經過去。

如果每一個當下,

我們不抓住,不去認真對待,

總想著看不見的明天或已經遠去的昨天,
我們就會永遠生活在緊張和失落中。

隨著生命一點點溜走,

到頭來留下的只能是三個字:“空悲切”。

所以,

如果想知道20年後會不會幸福,

就個人心態而言,
看看現在的狀態就可以知道:



如果你當下感到幸福,

20年後也應該會幸福;

如果你有太多的東西寄于明天,20年後,

這些願望無論是否實現,

你都可能不會感到真正的幸福。

幸福就在當下,

就在你手中的每一天,甚至每一刻,

而絕不在過去或者未來。

2012年4月10日 星期二

Google Chrome 搜尋結果靠左顯示

有時候不知按到那些鍵或設定到什麼, Google Chrome 搜尋結果會變成「置中」顯示。

若想要回復成預設值「靠左」顯示,可在Google Chrome 畫面上右上角,
按下「小板手」圖示,進入選像設定畫面,
左手邊功能選單中選「進階選項」
 -> 按下「內容設定」按鈕
 -> 按下「所有 cookie和網站資料」按鈕
 -> 在 cookie和網站資料 畫面右上角「搜尋 cookie」格位中,打入「google」字樣,找出與 Google 相關 cookie,然後將之刪除,儲存設定
 ->關閉 Google Chrome
 ->再次開啟 Google Chrome 即可。

---
Welly

2012年2月5日 星期日

ASP.NET 使用MasterPage跨網頁傳遞參數問題

一般跨網頁傳遞參數,很簡單到很多書都不講,大致有五種方法。
以送出頁為SendToB.aspx,接收頁為RecvFromA.aspx為例。

1.透過Http Html Form Get:
    送出頁:Response.Redirect("~/RecvFromA.aspx?id=" + TextBox1.Text);
    接收頁:string sId = Request.QueryString["id"];
    ◎通用性最佳,但不宜傳送可能有資訊安全疑慮之參數,且要注意參數編碼與轉碼問題。

2.透過Http Html Form Post:
    送出頁:Response.Redirect("~/RecvFromA.aspx"); 或使用 Button的PostBackUrl屬性填入~/RecvFromA.aspx。
    接收頁:string sId = Request.Form["id"];
    ◎通用性次佳,但在Master Page下無效。

3.透過ASP.NET PreviousPage:
    送出頁:Response.Redirect("~/RecvFromA.aspx"); 或使用 Button的PostBackUrl屬性填入~/RecvFromA.aspx。
    接收頁: TextBox oTB = (TextBox)this.PreviousPage.FindControl("TextBox1");
                     this.Label1.Text = oTB.Text;
    ◎只能用於本身且是ASP.NET網站。在Master Page下需要修改程式碼。

4.透過ASP.NET PreviousPage加自訂公用屬性:
    送出頁:先在Class內加上自訂公用屬性。
                  public String SearchString
                  {
                       get
                      {
                           return  TextBox1.Text;
                      }
                   }
                    再使用 Button的PostBackUrl屬性填入~/RecvFromA.aspx 。
    接收頁:將RecvFromA.aspx頁面的第一列後插入以下指令列,<%@ PreviousPageType VirtualPath="~/SendToB.aspx" %>
                    接著在RecvFromA.cs的Page_Load()函式中使用Label1.Text = PreviousPage.SearchString; 取得前頁公用屬性。
    ◎ 只能用於本身且是ASP.NET網站 ,且送出頁與接收頁無法二對一傳遞。不論一般跨網頁或Master Page下都不需要修改程式碼。

5.透過ASP.NET Session傳遞
    送出頁:使用 Button的onClick事件填入Session["SearchString"] = TextBox1.Text;
                    Response.Redirect("~/RecvFromA.aspx");
    接收頁:Page_Load()函式中使用Label1.Text =  Session["SearchString"].ToString();
    ◎ 只能用於本身且是ASP.NET網站,簡單好用跟寫 AP 觀念一樣。

但是,若使用MasterPage跨網頁傳遞參數,第一種方法可以,第二種方法會抓不到,第三種方法則接收頁需要修改語法如下,第四種方法可以,第五種方法可以。

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.PreviousPage != null)
        {
            if (PreviousPage.IsCrossPagePostBack)
            {
                //使用MasterPage時, 使用此語法來查找到前一頁中Content Page內的控制項
                TextBox oTB = (TextBox)PreviousPage.Master.FindControl("ContentPlaceHolder1").FindControl("TextBox1");
             
                //使用MasterPage時, 使用此語法來查找到前一頁中Master Page內的控制項
                //TextBox oTB = (TextBox)this.PreviousPage.Master.FindControl("TextBox1");
             
                //顯示上頁欄位中傳遞過來的參數
                this.Label1.Text = oTB.Text;
            }
        }
    }

---
Welly

2012年2月4日 星期六

淺析 ASP.NET Form Submit Keypress 事件 by Enter key

老一輩程式設計師都知道,以前在DOS下寫資料庫 AP,在畫面下按Enter鍵跳下一個欄位是預設再平常不過的事,但到了Windows AP下這功能是要自己在 Form.OnKeyPress事件寫處理指令,可是,到了ASP.NET WEB AP下這功能卻又成了預設功能,挺有趣。

ASP.NET Form Submit Keypress 事件 by Enter key其實說到底並不是ASP.NET 的程式設計問題,卻是關於Html Form 中的Submit 按鈕如何運作問題。


ASP.NET Form Submit Keypress 事件 by Enter key測試一:
當你的游標焦點進入某個表單控制項的時候,會啟動該表單中第一個(依Form 上控制項佈局,從左到右,從上至下算起) type="submit" 的按鈕(假如有),等待回應鍵盤及滑鼠的 Keypress 事件,以Submit該Form。
你可以測試一下以下程式碼:
   1. ﹤form action=""﹥
   2. ﹤input type="text" /﹥
   3. ﹤input type="submit" value="submit" /﹥
   4. ﹤/form﹥
   5. ﹤form action=""﹥
   6. ﹤input type="text" /﹥
   7. ﹤input type="button" value="submit" /﹥
   8. ﹤/form﹥


ASP.NET Form Submit Keypress 事件 by Enter key測試二:
在 ASP.NET 2.0 中的 Button 控制項,預設轉換成 Html 為 ﹤input type="submit"﹥,此時不一定要在 Form 的屬性宣告 submit 事件,因為,submit 型態按鈕就是用來提交Form ,在 ASP.NET 1.x時是轉換成 ﹤input type="button" onclick="_doPostBack(...)" /﹥,此普通 button 就不具備 submit 的上述預設提交行為。


ASP.NET Form Submit Keypress 事件 by Enter key測試三:
依上述,若想要禁用此項預設行為有二種方法。

(1)設置 Form 控制項的 DefualtButton 為你希望回應 Enter 的真正按鈕:
   1. ﹤form id="form1"
   2.
   3. runat="server"
   4.
   5. defaultbutton="Button1"﹥

◎注意 DefaultButton = ﹤ ﹤TargetButton.ID﹥﹥,因此這對複合控制項中,比如Login樣版的 Button 可能無效。
◎也可用程式動態指定 this.Form.DefaultButton = "ContentPlaceHolder1$btsubmit";
值得注意的是,如果用了Master Page,那麼要在按鈕ID前加上 Master 的ID:ContentPlaceHolderID和一個金錢符號($)。
◎例如:
‧在Master Page內用:
   1. protected void Page_Load(object sender, EventArgs e)
   2. {
   3.   this.Form.DefaultButton = "ctl00$ContentPlaceHolder1$Login2$LoginButton";
   4. }
‧在Content Page內用:
   1. protected void Page_Load(object sender, EventArgs e)
   2. {
   3.   this.Page.Form.DefaultButton = "ctl00$ContentPlaceHolder1$Login2$LoginButton";
   4. }
‧在一般(未使用Master Page)情況頁面內:
   1. protected void Page_Load(object sender, EventArgs e)
   2. {
   3.   this.Form.DefaultButton = "LoginButton ";
   4. }
‧在使用者自定控制項(.ascx)內:
   1.請先在引用該控制項的表單外部加一個 Panel 包住,
     <asp:Panel ID="Panel1" runat="server">
        .....//使用者自定控制項的內容
     </asp:Panel>
   2.然後再指定 Panel1.DefaultButton = "btsubmit";


(2)修改 Button 呈現方式 UseSubmitBehavior="false":
   1. ﹤asp:Button ID="Button1"
   2.
   3. runat="server" Text="Button"
   4.
   5. onclick="Button1_Click"
   6.
   7. UseSubmitBehavior="false" /﹥

◎個人建議採用(2)作法,簡單易記,效果明確。


另外,可以使用控制焦點的方式,過濾(擋掉) Enter 鍵按下的處理,做法是:
(1)記錄下需要設定過濾的焦點控制項ID,若不知可用獲取當前頁面焦點所在控制項的ID方法:
document.ActiveElement

(2)以ASP.NET Form上在TextBox1中輸入內容後,按下Enter鍵後,就執行Button1的click方法範例下,我們可在Page_Load事件方法中動態指定 TextBox1的屬性,依下寫入:
   1. TextBox1.Attributes.Add("onkeydown",
   2.
   3. "if(event.which || event.keyCode){
   4.
   5. if ((event.which == 13) || (event.keyCode == 13)) {
   6.
   7. document.getElementById('"+
   8.
   9. Button1.UniqueID+"').click();return false;}}
   10.
   11. else {return true}; ");

◎以上作法其實是針對 TextBox1的onKeydown 事件(或改成 Keypress 事件亦可)內,若按下的是 Enter 鍵時不執行下去,但若按下的是滑鼠左鍵,則執行下去。只能針對特定 TextBox 指定,萬一 Form 上有10個 TextBox 則要用 foreach 逐個指定。


參考資料來源:
1.浅析ASP.NET回车提交事件(转)
http://www.cnblogs.com/jiajiayuan/archive/2011/08/26/2154596.html

2. HtmlForm.DefaultButton 屬性
http://msdn.microsoft.com/zh-tw/library/system.web.ui.htmlcontrols.htmlform.defaultbutton(v=vs.80).aspx

3.Master page button event Overloading by content page button event when enter key is pressed
http://stackoverflow.com/questions/4303009/master-page-button-event-overloading-by-content-page-button-event-when-enter-key

4.ASP.NET 2.0 - Enter Key - Default Submit Button
http://geekswithblogs.net/ranganh/archive/2006/04/12/74951.aspx

5.如何讓使用MasterPage啟用 DefaultButton 屬性
http://www.wretch.cc/blog/bigdstut/14296848

6.Setting the default Button for a TextBox in ASP.NET
http://weblogs.asp.net/rajbk/archive/2003/12/11/setting-the-default-button-for-a-textbox-in-asp-net.aspx


---
Welly Lin