2008年9月29日 星期一

全球化(Globalization)與本地化(Localization)作法

Q: .net 程式如何實作多語系功能?

A: 多語系一般分為全球化(Globalization)與本地化(Localization)兩部份.

  1. 全球化(Globalization):將系統介面改成多國語言, 使用者可依喜好選擇他所要的語言.
  2. 本地化(Localization):針對貨幣、日期、數字等格式,依當地的文化顯示適當的格式.

在VS2005中可直接針對畫面設定Localizable屬性=True,並且切換Language屬性,之後即可依所定語言修改畫面,系統會自動產生資源檔;其他訊息也可每一語言自訂一資源檔儲存。

接著在程式中設定語系即可切換不同語系的系統介面,程式如下:

' 設定系統介面,即全球化(Globalization)

Thread.CurrentThread.CurrentUICulture = new CultureInfo(“zh-tw”)

' 設定貨幣、日期、數字等格式,即本地化(Localization)

Thread.CurrentThread.CurrentCulture = new CultureInfo(“zh-tw”)

That's all.

2008年8月20日 星期三

如何使用AJAX Javascript library?

Q: 如何使用AJAX Javascript library, 改變Radio Button的選項 ?

A: AJAX Javascript library 包含一個 $get 函數, 可輕易取得HTML控制項及asp.net server控制項,例如,表單上有一TextBox1控制項,只要在Javascript中使用

$get('TextBox1').value='test';

就可以在client端改變TextBox1控制項的內容了。


我作了一個簡單的例子,改變Radio Button的選項,程式如下:

只要使用$get('RadioButton1').checked = true; 就可以改變Radio Button的選項,很簡單吧!
但是進一步的問題來了, 如果使用Master Page該怎麼辦? 我的解法是在asp.net server端網頁產生上述的function, 秘訣是以 me.RadioButton1.ClientID 取得控制項名稱,加到 $get() 中。
mScript &= vbNewLine & "function setRadioButton(){ "
mScript &= "$get('" & Me.RadioButton1.ClientID & "').checked = true;"
mScript &= "}"
ClientScript.RegisterClientScriptBlock(GetType(XXX), "RadioButtonFunc", mScript)
其中XXX是類別名稱(class name)。

2008年7月23日 星期三

如何在執行階段指定SQLDataSource的參數值?

Q: SQLDataSource的SQL指令可以指定參數, 並繫結控制項、session、cookie或Query String值, 不幸的是要指定的變數值非以上任何一種, 應如何在執行階段指定參數值?

A: 很簡單, 只要在SqlDataSource1_Selecting 或其他 -ing的事件中指定即可, 例如下例, 指定參數userid值為login的用戶代號:
e.Command.Parameters("@userid").Value = User.Identity.Name

** 切不可使用
SqlDataSource1.SelectCommand &= " where userid = '" & User.Identity.Name & "'"

2008年7月20日 星期日

變數轉型的三種指令

Q: 我們常要在執行時期使用 FindControl 抓取某一控制項的屬性, 在存取屬性時須先轉換變數, 應該如何處理?

A: 轉換變數有三種方法:
1. CType
Ctype(obj, TextBox).Text --> 將 obj 轉為TextBox型態, 並取得Text屬性值
2. DirectCast, 参數與CType相同, 效率較佳, 但原始型別必須與欲轉換的型別完全相同, 縮小也不可。

3. TryCast, 参數與CType相同, 差別是轉換失敗也不會產生錯誤(exception), 只會將obj設為nothing。

2008年7月10日 星期四

response.redirect 不可出現在try...catch 中

Tips:response.redirect 不可出現在try...catch 中

response.redirect 會產生 exception, 而出現靈異現象, 例如

Try
...
connection1.Close()
Response.Redirect("CompanyGroup1.aspx")
Catch ex As Exception
Try : objTransaction.Rollback() : Catch : End Try
AlertMessage(Replace(Replace(Replace(ex.Message, """", ""), "'", ""), vbNewLine, "")) : Exit Sub
End Try

2008年7月3日 星期四

自動調整ComboBox寬度

Q:如何自動調整ComboBox寬度, 使其下拉自動展為最適合寬度?

A:加一ComboBox事件如下
Private Sub ComboBox1_DropDown(ByVal sender As Object, ByVal e As System.EventArgs)_
Handles ComboBox1.DropDown
Dim senderComboBox As ComboBox = DirectCast(sender, ComboBox)
Dim width As Integer = senderComboBox.DropDownWidth
Dim g As Graphics = senderComboBox.CreateGraphics()
Dim font As Font = senderComboBox.Font
Dim vertScrollBarWidth As Integer = _
IIf((senderComboBox.Items.Count > senderComboBox.MaxDropDownItems), _
SystemInformation.VerticalScrollBarWidth, 0)

Dim newWidth As Integer
For Each s As String In DirectCast(sender, ComboBox).Items
newWidth = CInt(g.MeasureString(s, font).Width) + vertScrollBarWidth
If width < width =" newWidth" dropdownwidth =" width" graphics =" senderComboBox.ComboBox.CreateGraphics()

2008年6月14日 星期六

ThreadPool 的用法

在多層式架構(N Tier Architecture)下, 中介層(Middle Tier)擔任工作分派(Dispatch)的任務, 接受前端程式的委託, 將各項工作以非同步方式同時執行, 執行後再將結果傳回; 這時我們常會碰到一個問題, 若前端程式的短時間內委託的工作過多, 會造成中介層負擔過重, 可能會使伺服器當機。因此中介層必須設定工作佇列(Task Queue), 讓過多的工作緩一緩, 等待前面委託的工作處理完, 再從佇列中取出執行, 這就是ThreadPool的功能。

以下是一個簡單的console程式範例, 唯一要注意的是執行緒內一定要用try...catch, 讓執行緒能正常結束。

Imports System
Imports System.Threading
Module Module1
' 非同步工作總數
Private mTaskCount As Integer = 3
Sub Main()
Dim mCompletionEvent As New AutoResetEvent(False) '全部工作完成的通知事件
Dim objStopWatch As New Stopwatch ' 馬錶
objStopWatch.Start() ' 啟動馬錶

' 設定集區的最大執行數及IO數
ThreadPool.SetMaxThreads(1, 1)

' 所有工作送入集區
For i As Integer = 1 To mTaskCount
' 設定執行緒參數
Dim objThreadParameters As New ThreadParametersClass
objThreadParameters.mThreadNumber = i
objThreadParameters.mCompletionEvent = mCompletionEvent

' 工作送入集區
ThreadPool.QueueUserWorkItem(New WaitCallback( _
AddressOf MyAsyncOperation), objThreadParameters)
Next
' 等待全部工作完成的事件通知
mCompletionEvent.WaitOne()

' 停止馬錶並顯示耗費時間
objStopWatch.Stop()
MsgBox(objStopWatch.ElapsedMilliseconds)
End Sub


' 執行緒之工作內容
Sub MyAsyncOperation(ByVal mThreadParameters As Object)
' 取得參數
Dim objThreadParameters As ThreadParametersClass = _
CType(mThreadParameters, ThreadParametersClass)
' 擷取錯誤
Try
Console.WriteLine("WorkItem {0} thread: Performing asynchronous operation.", _
objThreadParameters.mThreadNumber)

' 製造錯誤
If objThreadParameters.mThreadNumber = 2 Then
Dim ds As New DataSet
Console.WriteLine(ds.Tables(0).Rows(0).Item(0))
End If
' 停5秒
Thread.Sleep(5000) ' Sleep for 5 seconds to simulate doing work
Catch
Finally
' 待完成工作數減一
If Interlocked.Decrement(mTaskCount) = 0 Then
CType(objThreadParameters.mCompletionEvent, AutoResetEvent).Set()
End If
End Try
End Sub

' 參數定義
Public Class ThreadParametersClass
Public mThreadNumber As Integer

' ' *****不能使用 new, 因為要使用公共變數 *****
Public mCompletionEvent As AutoResetEvent
End Class
End Module