2009年10月30日 星期五

取得物件的私有欄位、呼叫已經綁定在物件上的事件

要 using System.Reflection、System.ComponentModel、System.Text 三個命名空間
public string ListFields(Type type)
{
  StringBuilder sb = new StringBuilder();
  FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
  sb.Append(@"<table border='1' cellpadding='3' cellspacing='0'><tr><th>Field Name</th>
              <th>Type</th><th>Static</th></tr>");
  foreach (FieldInfo fInfo in fieldInfos)
  {
    sb.AppendFormat("<tr><td>{0:s}</td><td>{1:s}</td><td>{2:s}</td></tr>",
      fInfo.Name, fInfo.FieldType.FullName, fInfo.IsStatic ? "Yes" : "No");
  }
  sb.Append("</table>");
  return sb.ToString();
}
這樣就可以把 type 裡面定義的私有欄位,用 Table 的方式顯示出來
如果私有欄位定義在 base class 中,則傳入 obj.GetType().BaseType
執行範例一: 
System.Web.UI.WebControls.FormView() FormView1 = new System.Web.UI.WebControls.FormView();
ListFields(FormView1.GetType());
Field Name Type Static
EventPageIndexChanged System.Object Yes
EventPageIndexChanging System.Object Yes
EventItemCommand System.Object Yes
EventItemCreated System.Object Yes
EventItemDeleted System.Object Yes
EventItemDeleting System.Object Yes
EventItemInserting System.Object Yes
EventItemInserted System.Object Yes
EventItemUpdating System.Object Yes
EventItemUpdated System.Object Yes
EventModeChanged System.Object Yes
EventModeChanging System.Object Yes
執行範例二: 
System.Web.UI.WebControls.DropDownList DopDownList1 = new System.Web.UI.WebControls.DropDownList();
ListFields(DropDownList1.GetType());
Field Name Type Static

??怎麼沒有東西??
那麼改用 ListFields(dropDownList1.GetType().BaseType) 試看看
Field Name Type Static
EventSelectedIndexChanged System.Object Yes
EventTextChanged System.Object Yes
果然有了!
拿到這些私有欄位的名稱有什麼用?各位發覺到了嗎,這些私有欄位都是以 Event 開頭的,也就是說這些是用來儲存 Delegate 的私有變數
接下來,就可以利用以下的程式,來呼叫「已經綁定在物件上的事件處理函式」
public void InvokeEvent(object obj, Type type, string eventName, EventArgs e)
{  
  PropertyInfo propertyInfo = (type.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic));
  EventHandlerList eventHandlerList = (EventHandlerList)propertyInfo.GetValue(obj, null);
  FieldInfo fieldInfo = type.GetField(eventName, BindingFlags.Static | BindingFlags.NonPublic);
  Delegate[] dels = eventHandlerList[fieldInfo.GetValue(null)].GetInvocationList();
  foreach (Delegate d in dels)
  {  
    d.Method.Invoke(d.Target, new object[] { obj, e });
  }
}
呼叫範例:
InvokeEvent(DropDownList1, DropDownList1.GetType().BaseType, "EventSelectedIndexChanged", e);

2009年6月17日 星期三

UpdatePanel 與 ValidationSummary 合併使用的注意事項

  1. Validator 以及由 Validator 驗證的控制項必須放在同一個 UpdatePanel 中
  2. ValidationSummary 也必須放在 UpdatePanel 中,可以跟 1 的不同

2009年4月17日 星期五

網路收音機 Ver0.61 更新事項

Ver 0.61 更新事項

  1. 因 HiChannel 修改了網路廣播的收聽方式,故作此更新
  2. 頻道下拉清單字體改小,以便更完整的顯示頻道名稱

WebRadio.xml 中修改的項目有:
  1. <URL ID="hinet"> 標籤的 URL 部份
  2. <CHANNEL> 標籤中,是由 HiChannel 提供服務的 SUBID 部份

老問題:用滑鼠點擊 Button 與按快速鍵行為不一致的解決方法

我們常常會將 Button.Caption 設定為像「&F. 檔案」這樣的內容,以便於將 Alt-F 快速鍵與 Button 連在一起
也常常會將一些輸入 Edit 的檢查,寫在 Edit.OnExit 事件處理函式中
假如這兩個碰在一起,就會發生用滑鼠點擊 Button 與按下快速鍵行為不一致的問題
因為按下快速鍵時,並不會轉移 Focus,會直接觸發事件處理函式,使得 Edit.OnExit 事件無法被觸發

解決方法如下:
於 Button.OnClick 事件處理函式的開頭加入以下兩行:

if (Sender as TWinControl).CanFocus then
  (Sender as TWinControl).SetFocus;

這樣強迫轉移 Focus,就可以解決這個問題了

2009年3月10日 星期二

Crystal Report 的民國100年問題

Crystal Report (8、9、11) 的日期物件,若選用「中華民國曆」格式的話,「年」只會出現兩位
使得民國 100 年變成了「00」
可以使用以下的公式來處理 (Crystal 語法)
Trim(CStr(Year(日期) - 1911, '#00')) + '/' + CStr(Month(日期), '00') + '/' + CStr(Day(日期), '00')

2012/03/06 更新:原先的版本沒有考慮到 null 的問題,改成以下這樣
if (aDate >= CDate('1899/12/31')) then
  Trim(CStr(Year(aDate) - 1911, '#00')) + '/' + CStr(Month(aDate), '00') + '/' +  CStr(Day(aDate), '00')
else
  ''

2009年3月4日 星期三

Delphi 2009 的函式說明自動完成模板

選擇 File -> New -> Other -> Code Template
將以下內容貼進去然後存檔
就可以按 Ctrl-J 選擇 summary,或是輸入 summary 之後按 Ctrl-J 自動出現函式說明的標籤了

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate    xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
                version="1.0.0">
    <template name="summary" invoke="auto">
        <point name="comment">
            <hint>
                函數的說明文字
            </hint>
            <text/>
        </point>
        <description>
            Help Insight XML Documentation comment with "summary" element
        </description>
        <author>
            CodeGear
        </author>
        <code language="Delphi" context="methodbody" delimiter="|"><![CDATA[
/// <summary>
///   |comment|
/// </summary>
///   <param name="">
///   </param>
///   <param name="">
///   </param>
///   <param name="">
///   </param>
/// <returns>
/// </returns>
/// <remarks>
/// </remarks>]]>
        </code>
    </template>
</codetemplate>