我的雲端生活網 - Life+

Sunday, June 24, 2007

[微程式-技術研討會]微軟 asp.net 2.0 ajax

微軟Asp.net2.0 Ajax
一. Asp.net 2.0 Ajax
執行環境需求:
Framework 2.0
IIS
開發環境:
VS2005 C#.net (or VB.net)
微軟 Ajax 套件 (需另外下載)
1.下載套件:
http://ajax.asp.net/
於首頁 按下 Download ASP.NET AJAX v1.0

會進入下一個頁面
點下 Download ASP.NET Extensions V1.0 即可 下載

安裝完成後 開啟 VS2005
新增專案  選擇(VB 或 C#) Asp.net Ajax-Enabled Web Application

開啟後會發現 多了 1組元件在 工具箱 (Ajax Extensions)

2.介紹AJAX Extensions
ASP.NET AJAX v1.0 使用微軟自定的 Client Script Libery
1.ScriptManager控制項 – 整個 Asp.net Ajax 的核心 ,所有要使用Ajax的功能均必須使用該元件 ,負責建立User端的javascript ,使用Ajax功能時只能有一個ScriptManager控制項。
2.UpdatePanel控制項 – 與ScriptManager搭配使用後 ,可以簡單建立完成Ajax功能。
3.UpdateProgress控制項 – 與UpdatePanel 配合 ,用來顯示 非同步postback的處理狀況 ,或將非同步postback中斷。
4.Timer 控制項 – 就如同windows應用程式所使用的Timer 元件 ,可定時於page中重整 ,但時間設定太短可能會增加Server的負擔。
5.ScriptManagerProxy 控制項 – 在Asp.net Ajax的page裡只能用一個ScriptManager, 於Asp.net MasterPage(類似Html 的框架頁)會有多個Asp.net page,如果同時間有2個以上的網頁要使用Ajax功能需使用到 ScriptManager 則子版面必須使用ScriptManagerProxy

範例(一) AspNetAJAXdemo.aspx
配合 Asp.Net 2.0 的MasterPage 解說 這5大Asp.Net Ajax 控制項 的使用方式

二. Asp.Net Ajax Control Toolkit
Asp.Net Ajax Control Toolkit 為 Asp.Net Ajax 的強化套件 , 已有34項免費延伸元件可以直接使用,這件元件是由先前所介紹的那5個控制項所擴充而成
1. 下載
一樣至 http://ajax.asp.net/ 點選 Download ASP.NET AJAX v1.0 後出現以下畫面
點選 Download the ControlToolKit

2.新增至工具箱 加入索引 選擇項目  瀏覽  選擇剛剛下載的檔案裡位於 SampleWebSite\bin 中的 AjaxControlToolKit.dll



















成功後工具箱將出現34種擴充元件可以使用


列舉幾個元件進行解說
1.TextBox 自動完成 (範例 AutoComplete.aspx)
AutoCompleteExtender
屬性:TargetControlID = 要被設定的TextBox 的ID
ServiceMethod = 後端所使用的Web Service( 或PageMethod)
ServicePath = WebService 的位置 , 不設定會自動判定使用 PageMethod
MinimumPrefixLength = 至少輸入多少字元後動作
CompletionInterval = 輸入多久後執行WebService的延遲時間(毫秒)
EnableCaching = 是否啟用 Caching
CompletionSetCount = 要回傳顯示的 item數

範例重點解說:
protected void Page_Load(object sender, EventArgs e) {
//設定 TargetControlID
AutoCompleteExtender1.TargetControlID = this.TextBox1.ID;
//輸入的字元長度
AutoCompleteExtender1.MinimumPrefixLength = 1;
//啟用Caching
AutoCompleteExtender1.EnableCaching = true;
//顯示的item數
AutoCompleteExtender1.CompletionSetCount = 15; //最多15筆
AutoCompleteExtender1.ServiceMethod = "GetEmailList";
}
//pageMethod
[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public static String[] GetEmailList(String prefixText,int count) {
//prefixText =輸入的字串 , count 要回傳的數目
//連結DB做過濾
String Constr = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + @"D:\研討會Ajax\SolutionExp\Example2\DB\mail.mdb";
String sql = "select Top "+ count +" * from mail where mail like '"+ prefixText.Trim() +"%' order by mail";//取得mail清單
OleDbConnection conn = new OleDbConnection(Constr);
OleDbDataAdapter da = new OleDbDataAdapter(sql, conn);
DataTable dt = new DataTable();
da.Fill(dt);
String[] data = new string[dt.Rows.Count];
for (int i = 0; i < data.Length; i++) {
DataRow row = dt.Rows[i];
data[i] = row["mail"].ToString(); //取出mail
}
return data; //回傳String Array

}

2.自由拖曳panel(範例 DragPanel.aspx)
DragPanelExtender
屬性:TargetControlID = 要被拖曳的Panel 的ID
DragHandleID = 觸發拖曳事件的panel ID
*DragHandle 和 TargetControl 可為相同panel , 如不一樣,DragHandle的panel必須建立於TargetControl的panel 中
範例重點解說:
protected void Page_Load(object sender, EventArgs e) {
DragPanelExtender1.TargetControlID = this.Panel1.ID; // 要移動的panel;
DragPanelExtender1.DragHandleID = this.Panel2.ID;//觸發移動事件的panel;
this.Panel1.Style["cursor"] = "hand"; //滑鼠移到panel2 後游標變 成 hand
}

3.可拖曳放大縮小的網頁物件(範例 ResizableControl.aspx)
ResizableControl
屬性:
TargetControllID = 要改變大小的控制項
HandleCssClass = 拖曳點CSS設定
ResizableCssClass = 拖曳中的CSS設定
MinimunWidth = 拖曳時可接受的最小寬度
MinimunHeight = 拖曳時可接受的最小高度
MaxmumWidth = 拖曳時可接受的最大寬度
MaxmumHeight = 拖曳時可接受的最大高度
OnClientResize = 拖曳後要執行的javascript
OnClientResizing = 拖曳中要執行的javascript
OnClientResizeBegin = 拖曳前要執行的 javascript
HandleOffsetX = 拖曳點於物件右下角的X座標
HandleOffsetY = 拖曳點於物件右下角的Y座標
範例重點解說:
Css
<style type="text/css">
/* ResizableControl */
.frameImage
{
/* panel(圖片)大小 */
width:180px;
height:130px;
overflow:hidden;
float:left;
padding:3px;
}

.handleImage
{
/* 可拖曳圖示 */
width:15px;
height:16px;
background-image:url(Image/HandleHand.png);
overflow:hidden;
cursor:se-resize;
}

.resizingImage
{
padding:0px;
border-style:solid;
border-width:3px;
border-color:#B4D35D;
}

Javascript 抓取物件(panel1)大小 於Lable1中顯示
<script>
function onOK(){
$get('Label1').innerHTML=$get('Panel1').style.height + ',' + $get('Panel1').style.width;
}
</script>

主要程式碼
protected void Page_Load(object sender, EventArgs e) {
//拖曳圖示
ResizableControlExtender1.HandleCssClass = "handleImage";
//拖曳中的圖示
ResizableControlExtender1.ResizableCssClass = "resiaingImage";
//設定目標控制項
ResizableControlExtender1.TargetControlID = Panel1.ID;
//javascript function OnOK
ResizableControlExtender1.OnClientResize = "onOK";
//avascript function OnOK
ResizableControlExtender1.OnClientResizing = "onOK";
//最小高度
ResizableControlExtender1.MinimumHeight = 100;
//最小寬度
ResizableControlExtender1.MinimumWidth = 100;
}

4.Asp.net 2.0 Ajax應用 電子地圖
顯示頁面:DemoMap.aspx
處理頁面:GetMap.aspx
DemoMap.asp 程式碼
Javascript 在處理 拖曳panel 座標
<script type="text/javascript">
//位移變數
var offsetX,offsetY,startX,startY;
var isMoving; //開始移動Flag

function _start(){
//設定開始移動
isMoving=true;
//紀錄起點
startX=event.x;
startY=event.y;
startY=startY+17;
}
function _move(){
//如果在移動中模式
if (isMoving==true){
//移動
offsetX=event.x-startX;
offsetY=event.y-startY;
//設定圖檔位置
$get('Image1').style.left=10+(offsetX);
$get('Image1').style.top=130+(offsetY);
}
}
function _end(){
//如果在移動中模式
if (isMoving==true){
//設定處理完畢
isMoving=false;
//計算調整位移
offsetX=-(event.x-startX);
offsetY=-(event.y-startY);
offsetY= offsetY-17;
//以計算出的位移重新載入地圖
if (offsetX!=0 && offsetY!=0)
$get('Image1').src='GetMap.aspx?offsetX='+offsetX+'&offsetY='+offsetY+'&width=500&height=500';
$get('Image1').style.left=10;
$get('Image1').style.top=110;
}
}
</script>

DemoMap.aspx.cs
此function為在CS檔中直接定義 aspx中Panel_phantom 的Style 與javascrip操作事件
private void MakePhantom() {
Panel_phantom.Style["filter"] = "alpha(opacity=1);";
Panel_phantom.Style["cursor"] = "hand";
Panel_phantom.Style["position"] = "absolute";
Panel_phantom.Style["left"] = "15";
Panel_phantom.Style["top"] = "110";
Panel_phantom.Attributes["onmousedown"] = "_start();";
Panel_phantom.Attributes["onmouseup"] = "_end();";
Panel_phantom.Attributes["onmouseleave"] = "_end();";
Panel_phantom.Attributes["onmousemove"] = "_move();";
}
MapGotoXY 為 取得物件 Image1 的圖片來源 呼叫 GetMap.aspx 加上參數處理後,輸出所要顯示的圖片區塊
private void MapGotoXY(String x, String y) {
Image1.ImageUrl = "GetMap.aspx?x=" + x + "&y=" + y + "&width=500&height=500";
txb_x.Text = x ;
txb_y.Text = y ;
//設定拖曳用的Panel機制
MakePhantom();
}//MapGotoXY
GetMap.aspx
主要處理 地圖的顯示座標
protected void Page_Load(object sender, EventArgs e) {
//Image 的x,y 座標
int x =Convert.ToInt32(Request.QueryString["x"]);
int y =Convert.ToInt32( Request.QueryString["y"]);
//移動的 x,y座標
int offsetX = Convert.ToInt32(Request.QueryString["offsetX"]);
int offsetY = Convert.ToInt32(Request.QueryString["offsetY"]);
//地圖寬高
int width = Convert.ToInt32(Request.QueryString["width"]);
int height= Convert.ToInt32(Request.QueryString["height"]);

Bitmap bmp ;
Bitmap retbmp;
//讀入檔案
String ImgPath = Path.GetDirectoryName(Request.PhysicalPath) + @"\Image\tw.jpg";
bmp = new Bitmap(ImgPath);
if (x == 0 && y == 0 && offsetX != 0 && offsetY != 0) {
x = Convert.ToInt32(Session["_LastX"]) + offsetX;
y = Convert.ToInt32(Session["_LastY"])+ offsetY;
}
//防呆
if (x < 1) x = 1;
if (y < 1) y = 1;
if (x + width > bmp.Width) x = bmp.Width - width;
if (y + height > bmp.Height) y = bmp.Height - height;

//記錄 X,Y 座標
Session["_LastX"] = x;
Session["_LastY"] = y;

//宣告 GetMap 的輸出格式
Context.Response.ContentType= "image/Jpeg";
Context.Response.BufferOutput = false;
//建立矩形
Rectangle rect = new Rectangle(x, y, width, height);
retbmp = bmp.Clone(rect, bmp.PixelFormat); //取得圖片區塊
//處理圖形品質
System.Drawing.Imaging.ImageCodecInfo[] codecs = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.ImageCodecInfo ici = null;

//找出Encoder
foreach( System.Drawing.Imaging.ImageCodecInfo codec in codecs){
if( codec.MimeType == "image/jpeg") {
ici = codec;
}
}
//參數 - 高品質圖檔
System.Drawing.Imaging.EncoderParameters ep = new System.Drawing.Imaging.EncoderParameters();
ep.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, Convert.ToInt64(100));
retbmp.Save(Context.Response.OutputStream, ici, ep); //儲存
bmp.Dispose(); //釋放
retbmp.Dispose(); //釋放
Context.Response.End();//結束
}
5. 建立 統計圖
程式碼請參考
Chart..aspx
LineChart.cs
Chart..aspx主要顯示頁
LineChart.cs 為建立統計圖-點線圖的主要程式
輸出的圖 配合拖曳標籤可以自由移動圖表(使用DragPanelExtender)
如下方圖示

6. Ajax Excel圖表
程式碼過多 請參考
Excel_Demo.aspx
ExcelTable.cs
LineChart.cs
Excel_Demo.aspx 為主要顯示頁
背後處理程式有 ExcelTable.cs 與 LineChart.cs
ExcelTable.cs 提供3個funtion
1. reDrawExcelTable – 用來建立 table物件配合Javascript讓user感覺很像Excel
2. ExportDataTable –將Table轉化成DataTable提供給LineChart.cs
使LineChart 繪製圖片
3. SetValue – 初始化設定欄位的值

下圖為執行結果


Asp.Net2.0 配合 Ajax1.0 套件可以讓開發人員短時間之內,建出效果不錯的網頁,擴充元件讓頁面上只留下元件使用的標籤,除了微軟提供出的34項免費的基本元件可以使用外,也可以自行建立擴充元件 (Extender) , 至於要如何建立自訂的擴充元件,因為該功能步驟繁雜,等待小弟研究透徹後 ,有機會再向各位解說。

Tuesday, June 5, 2007

socket 程式應該注意的參數

這幾天再寫jabber component 時發生一個奇怪的問題, 伺服器與component 固定一段時間就會終止通訊,然而連線此時還是存在的,伺服器或客乎端都沒有當掉,而且一般的jabber client 連接在上面也沒有問題,惟獨自己實做的server與client 無法通訊,後來發現;幾個socket 重要的參數,當client需要樣長時間連線時這些參數格外重要:

setsockopt SOL_SOCKET, SO_KEEPALIVE
setsockopt IPPROTO_TCP, TCP_KEEPIDLE
setsockopt IPPROTO_TCP, TCP_KEEPCNT
setsockopt IPPROTO_TCP, TCP_KEEPINTVL

程式再加了這些tcp 參數設定後,症狀完全消失

Blog Archive