當DataGrid遇見100萬筆資料
DataGrid遇見100萬筆資料會發生什麼事呢?以下是在藍色小舖的應答
【作者:奚江華.聖殿祭司】
原問題網址:http://www.blueshop.com.tw/board/show.asp?subcde=BRD20050216141103C3Y&fumcde=FUM20041006161839LRJ
效能永遠不夠,所以Performance的議題永遠存在,而原因分為兩個部分:
1.人為
2.系統(軟體和硬體)
而你的8000筆的資料量的問題,剛好同時Cover到上面兩個原因。
我有個ASP.NET網頁報表軟體,使用MSDE 2000,資料庫檔案大小為900MB,裡面有二個龐大的Table,一個約1,700,000筆(30多個欄位),另一個為380,000筆(約15個欄位),每個月資料比數以幾十萬比的成長率在持續增加;在P4-2.8G而記憶體512MB環境中執行,每次查詢會有3~5萬個Table Cells顯示,但查詢在一秒內就可以顯示完畢(但這中間是經過許多層次的最佳化和調校才能達成的,註:Table沒有作Join查詢);而和你的8000筆資料+DataGrid對ASP.NET而言絕對不會有問題,只是手法要改一下,不能老是依賴Default的東西。
但為了為了要和你的問題有個客觀比對,依你的條件,我首先在我的NB做了同樣的模擬測試,NB測試環境如下:
1.OS:Windows 2003 Server標準版
2.Visual Studio.NET 2003
3.MS SQL Server 2000標準版
4.CPU:Pentium-M 1.8G
5.記憶體:512MB
我開機後記憶體使用量為205MB,而有個資料庫有近160,000筆的資料,欄位數則有15個,我的程式碼如下:
SqlConnection conn=new SqlConnection("data source=.;initial catalog=LK;user id=sa;password="admin");
conn.Open();
SqlDataAdapter da1=new SqlDataAdapter("select top 8000 * from lm1200detail",conn);
DataSet ds=new DataSet();
da1.Fill(ds,"ABC");
conn.Close();
DataGrid1.DataSource=ds.Tables["ABC"].DefaultView;
DataGrid1.DataBind();
da1.Dispose();
ds.Dispose();
以上為8000筆資料,15個欄位,執行結果分幾點來說明:
1.在我的SQL Analyzer中執行row筆數的計算select Top 10000 * from lm1200detail,第一次不計,以第二次以後是SQL Analyzer顯示為0秒,也就是不到1秒。
2.執行ASP.NET的DataGrid顯示後,CPU的使用率立刻爆增到100%,持續了20秒才完成,但DataGrid依然把所有的資料量顯示完。
3.記憶體由205MB爆增到422MB,一共增加了217MB(吃得兇)。
所以你應隱約知道這樣子的系統存在了哪些問題了吧?
OK,有了上面的數據樣本我們可以開始討論正題了(這樣的測試數據應比你的數據還嚴苛吧),問題在哪裡呢?
基本上為了釐清你的問題,必須切割和隔離成三個層次,如下:
1.SQL Server層
2.ADO.NET層
3.DataGrid控制項層
為何要切割成這三個層次?因為這三層每個地方都有問題,簡述如下:
1.SQL Server->沒有最佳化問題
2.ADO.NET->DataSet對大量資料處理的問題
3.DataGrid控制項->對大量資料處理及分頁的問題
接著開始探討你所碰到的問題:
SQL Server部分的問題:
1.SQL Analyzer執行5秒有點久,但如果你做8000多筆多個Table Join的話則Maybe合理,但還需進一步分析是否有改進空間。
2.你用的是View,View上面當然不能加索引(Index),但這樣一來你Join多個Table時,就會造成效能上的問題,速度比起叢集索引Clustered及非叢集索引Non Clustered可能會慢上3~10倍不等的可能性,其決定於SQL Server的最佳化引擎是否有作用。
3.解決索引問題當然不能在View上加,而是要在Join的相關Table加上索引,而索引建立的原則是依T-SQL查詢語法的where條件式為依據,通常是Relation的Key上去建立索引;然後你可以去比對有索引和沒索引的執行秒數,應會差不少,但最客觀的是你必須去查看SQL Server的最佳化引擎是如何Parse你的 T-SQL語句,用Execution Plan去分析SQL Server是以何種方式執行你的SQL Server語句,若是用Table Scan執行的表示,你一點也沒用到索引,若用到任何的索引則表示SQL Server最佳化引擎有在作用。
4.Server的最佳化引擎是否有作用取決於1.你的T-SQL語法後的where條作子句2.你建立的索引對不對?!
Execution Plan圖片參考網址: 


ADO.NET的問題:
1.在ADO.NET之中DataSet是一個In Memory的Database,也就是存在於記憶體中的資料庫,一般資料庫中有的基本特性它都有,資料量幾千幾萬筆難不倒它,但若幾十萬筆~100萬筆呢?可能在ASP.NET環境中DataSet就是一個大問題,會非常的不經濟(和ASP.NET、IIS及AP Server運作的方式原理有關,但在這不深入說明),但是它的承載性究竟被設計到多大是一個未知數?!有空大家可以去測試一下…
2.SqlDataAdapter.Fill(ds)這樣的動作,要耗費多少記憶體空間和運算成本cost?且在你的程式碼之中,因為ASP.NET”無狀態”的特性,若每次DataSet中Fill 8000筆資料,耗費幾十MB~100MB,用完一次就丟棄了,你覺得能負荷多少人?若以我的經驗,如果是DataSet每次用掉100MB記憶體空間,不到10次就會Timeout掉了。
3.對DataSet而言,即使你一頁只看30筆資料,8000筆-30筆=7970筆,對系統資源而言,不但7970筆資料也要吃掉記體不說,最後耗費系統成本來處理這些沒用的7970筆廢物般的資料,活似個拖油瓶。
4.DataGrid不分頁一次顯示的話會更慘。
DataGrid的問題:
1.DataGrid不論有沒有做分頁Page,它都必須先照單全收這8000筆資料,然後再進行加工處理,選出這個Page所需的30筆,你想這樣會快嗎?等你資料成長到16000筆時,就是從16000筆中選出你分頁Page要的30筆…會更慢。從SQL Server->ADO.NET DataSet->DataGrid都在傳送非常不經濟且大量的資料,對系統記憶體、效能與CPU運算有著很大的傷害。
2.DataGrid分頁Page換頁時又是什麼動作?它會觸發一個PageIndexChange的事件,裡面又要重作一次Fill(DataSet)的動作,又來一次8000筆的Fill,然後再丟給DataGrid,所以說程式怎麼會快得了呢?(在大量資料用DataGrid來處理)。
3.在Http技術的Stateless無狀態特性下,所有資源,除非你用狀態管理(Application、Session、ViewState)來處理、宣告為Static或元件的技術,否則所有資源用過後即會被丟棄,不能再重用了。
4.DataGrid在大量唯讀資料時,對於EnableViewState屬性應設為false,因為ViewState會耗費大量可觀的記憶體,你用DataGrid不分頁來一次顯示8000筆你就會知道true與false兩者的差別了,兩者落差可能會高達30~60MB不等(對30000~60000個Table Cell而言)。
解決之道:
首先我必需說明這不是ASP.NET或任何系統的錯,純粹是沒有好的方法來處理這樣的問題,是手法面要改一下!
SQL Server部分:
1.請建立有效索引,無論是叢集索引或非叢集索引索引,或是複合索引都好,甚至必要時還要指定索引的升降冪,減少不必要的Order By。
2.請用Execution Plan來確認最佳化引擎有採用到你的索引,where條件子句是最佳化引擎分析的關鍵。
3.你的5秒在上面兩點作用後,一定要有顯著的改進,才算解決SQL Server這層的問題!
DataGrid及DataSet的問題:
1.基本上DataGrid+DataSet在遇見大量資料時,會變得氣喘如牛,系統資源鉅幅的耗盡(前面已說過了),所以若資料很大時,請用top xxx來限制有效資料量,緩解DataSet及DataGrid的壓力。
2.不能用Top時,請用T-SQL或Store Procedure來取回該頁Page所需的30筆資料即可,這就需要一點加工了:
(1)先計算出總筆數,然後總筆數/30=Page頁數,再以自訂方式產生DataGrid作頁碼分頁用。
(2)依DataGrid目前所在的PageIndex去呼叫資料存取層,也就是只要Fill(DataSet)填入30筆回傳即可。
3.最後記得Connection要close,SqlDataAdapter和DataSet也要Dispose,釋放掉系統資源。
基本上這樣你的系統就會變得非常的”輕”,速度會飛馳增加十倍以上都不成問題,即使你資料量成長到100萬筆以上,依然Power!
註:
1.SQL Server 2005就支援了ADO.NET的Page,只取回你Page所需的Row,對系統效能和設計會有很大的幫助。
2.關於分頁只取回該頁Page及SP的程式碼,請花點時間做功課,真的研究不出來時再回我,我再Post參考程式碼給你。
有空參觀我的Blog吧http://blog.sina.com.tw/weblog.php?blog_id=4907
其實在這有很多高手,大家各有所長,互相交流一下而已,剛好曾經花了很多時間研究大量資料時,ASP.NET與ADO.NET效能的問題,因為我系統再過一陣子就破200萬筆了,順道是測試一下MSDE 2000的能耐,沒想道竟這麼Power,MSDE 2000+ADO.NET離線式真的可以搭配得很好,又可以說免錢的,還可以用Enterprise Manager來作管理,真的是省了一筆銀子,把心得公布給大家知道,承蒙各位不棄就好!
分頁的技巧有兩種,一種是直接透過T-SQL,另一種是透過Store Procedure,在這Post出來跟大家分享一下:
T-SQL:
假設Northwind有一個Customer的Table,你需要取回41~50筆的記錄,T-SQL語法該如何作呢?
Select Top 10 CustomerID,CompanyName,ContactName,Country from Customers where CustomerID Not in
(Select top 40 CustomerID from Customers order by Country,CustomerID)
Order by Country,CustomerID
Store Procedure:
出自MSDN Magazine,是別人的智慧
CREATE PROCEDURE northwind_OrdersPaged
(
@PageIndex int,
@PageSize int
)
AS
BEGIN
DECLARE @PageLowerBound int
DECLARE @PageUpperBound int
DECLARE @RowsToReturn int
-- First set the rowcount
SET @RowsToReturn = @PageSize * (@PageIndex + 1)
SET ROWCOUNT @RowsToReturn
-- Set the page bounds
SET @PageLowerBound = @PageSize * @PageIndex
SET @PageUpperBound = @PageLowerBound + @PageSize + 1
-- Create a temp table to store the select results
CREATE TABLE #PageIndex
(
IndexId int IDENTITY (1, 1) NOT NULL,
OrderID int
)
-- Insert into the temp table
INSERT INTO #PageIndex (OrderID)
SELECT
OrderID
FROM
Orders
ORDER BY
OrderID DESC
-- Return total count
SELECT COUNT(OrderID) FROM Orders
-- Return paged results
SELECT
O.*
FROM
Orders O,
#PageIndex PageIndex
WHERE
O.OrderID = PageIndex.OrderID AND
PageIndex.IndexID > @PageLowerBound AND
PageIndex.IndexID < @PageUpperBound
ORDER BY
PageIndex.IndexID
END
以上的東西不藏私和大家分享一下,其實我相信如果你自己花多點心思說不定可以寫出比上面更好的演算法,算是拋磚引玉囉,有更好的方法希望大家貼出來一起分享!
【作者:奚江華.聖殿祭司】

本文引用網址:http://blog.sina.com.tw/dotnet/article.php?pbgid=4907&entryid=3921


◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()

http://blog.csdn.net/21aspnet/archive/2007/03/25/1540301.aspx 

◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()

十幾行程式碼搞定 Master-Detail GridView(內含子 GridView)





0


摘要


在網路上看到很多 GridView 內含子 GridView 的範例,雖然方法不同不過程式碼都有點小複雜,想說難道沒有更簡單易懂的方法嗎?
在此文章中將用十幾行的程式碼,就教你快速學會並搞定這種 Master-Detail GridView 的需求。


程式碼實作


我們以 Northwind 資料庫為例,首先在頁面上放置二組 GridView+SqlDataSoruce,分別繫結至 [Orders] 、[Order Details] 這二個資料表。



我們先來看一下它的程式碼及執行結果,後續再做進一步的詳細說明。
我們只要在 GridView 的 RowDataBound 事件撰寫下面十幾行的程式碼就完成了,不要懷疑這已經是全部的程式碼。


















































1Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound     
22     If (e.Row.RowState And DataControlRowState.Selected) = DataControlRowState.Selected Then    
33         Dim oRow As New GridViewRow(0, -1, DataControlRowType.DataRow, e.Row.RowType)     
44         GridView2.Visible = True    
55         GridView2.DataBind()     
66         Dim sHTML As String = Bee.Web.WebFunc.ControlToHTML(GridView2)     
77         GridView2.Visible = False    
88         Dim oCell As New TableCell     
99         oCell.Text = sHTML     
1010         oCell.ColumnSpan = e.Row.Cells.Count     
1111         oRow.Cells.Add(oCell)     
1212         e.Row.Parent.Controls.AddAt(e.Row.RowIndex + 2, oRow)     
1313     End If    
開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound 2 If (e.Row.RowState And DataControlRowState.Selected) = DataControlRowState.Selected Then 3 Dim oRow As New GridViewRow(0, -1, DataControlRowType.DataRow, e.Row.RowType) 4 GridView2.Visible = True 5 GridView2.DataBind() 6 Dim sHTML As String = Bee.Web.WebFunc.ControlToHTML(GridView2) 7 GridView2.Visible = False 8 Dim oCell As New TableCell 9 oCell.Text = sHTML 10 oCell.ColumnSpan = e.Row.Cells.Count 11 oRow.Cells.Add(oCell) 12 e.Row.Parent.Controls.AddAt(e.Row.RowIndex + 2, oRow) 13 End If


執行程式,選取 GridView 的某一資料列,就會展開其子 GridView 。執行換頁動作,一樣可以正常展開子 GridView。




接下來說明這個範例的一些細節,Master GridView 繫結 [Orders] 資料表,設定 DataKeyNames="OrderID",當選取某筆資料時,GridView 的 SelectedValue 就是該筆資料的 OrderID 欄位值。另外設定 GridView 的 EnableViewState="False",這個設定主要是讓 GridView 選取時都會重新做 DataBind 的動作。













1<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"    
22     DataKeyNames=
"OrderID" DataSourceID="SqlDataSource1" EmptyDataText="沒有資料錄可顯示。"     3 3     ForeColor="#333333" GridLines="None" AllowPaging="True" EnableViewState="False">     " originalcode=" ">開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4" 2 DataKeyNames="OrderID" DataSourceID="SqlDataSource1" EmptyDataText="沒有資料錄可顯示。" 3 ForeColor="#333333" GridLines="None" AllowPaging="True" EnableViewState="False">


再來就是 Detail GridView 繫結 [Order Details] 資料表,一樣設定 GridView 的 EnableViewState="False",且設定 Visible="False",也就是初始狀態 Detail GridView 是隱藏的。



















1<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" BackColor="LightGoldenrodYellow"    
22     BorderColor="Tan" BorderWidth="1px" CellPadding="2" DataKeyNames="OrderID,ProductID"    
33     DataSourceID="SqlDataSource2" EmptyDataText="沒有資料錄可顯示。" ForeColor="Black" GridLines="None" Visible="False" EnableViewState="False">    
4 view plain | print | copy to clipboard | ?   
view plain | print | copy to clipboard | ? " originalcode=" view plain | print | copy to clipboard | ? ">開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?

<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" BackColor="LightGoldenrodYellow" 2 BorderColor="Tan" BorderWidth="1px" CellPadding="2" DataKeyNames="OrderID,ProductID" 3 DataSourceID="SqlDataSource2" EmptyDataText="沒有資料錄可顯示。" ForeColor="Black" GridLines="None" Visible="False" EnableViewState="False"> view plain | print | copy to clipboard | ?


Detail GridView 所繫結的 SqlDataSource 控制項,將其 SelectParameters 的 @OrderID 參數關連至 Master GridView 的 SelectedValue。



















1<SelectParameters>    
22     <asp:ControlParameter ControlID="GridView1" Name="OrderID" PropertyName="SelectedValue"    
33         Type="Int32" />    
44 </SelectParameters>    
4 " originalcode=" 2 4 ">開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?

<SelectParameters> 2 <asp:ControlParameter ControlID="GridView1" Name="OrderID" PropertyName="SelectedValue" 3 Type="Int32" /> 4 </SelectParameters>


再來還有一個重要步驟,就是在 aspx 程式碼中,要設定 Page 的 EnableEventValidation="false",因為我們動態將 Detail GridView Render 出來插入 Master GridView 中,整個控制項階層都被異動,這樣會造成事件驗證失敗。










1<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default5.aspx.vb" Inherits="Default5" EnableEventValidation="false" %>  
" originalcode=" ">開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default5.aspx.vb" Inherits="Default5" EnableEventValidation="false" %>


另外在 Master GridView 的 RowDataBound 事件中,有一個 ControlToHTML 方法是取得 Detail GridView 的 HTML 碼,這個方法可以參考筆者另一篇「使用 BasePage 來解決 GridView 執行 RenderControl 產生的錯誤」文章有詳細說明。










1Dim sHTML As String = Bee.Web.WebFunc.ControlToHTML(GridView2)  
開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?

Dim sHTML As String = Bee.Web.WebFunc.ControlToHTML(GridView2)
 
本文引用網址:http://itgroup.blueshop.com.tw/jeff377/blog?n=convew&i=2086




◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()


CSS 半透明效果


超簡單的一行,又有灌水的嫌疑~哈哈!還有,到底什麼時候 IE 才會支援 CSS3 啊!


#transparent {filter:alpha(opacity=50); -moz-opacity:0.5; opacity:0.5;}

 

-----------------------------------------------------------------------

One Response to “CSS 半透明效果”



moz-opacity:0.5;
可以不用加了~
Firefox已經可以吃下opacity了

 

本文引用網址:http://atedev.wordpress.com/2008/09/12/css-%e5%8d%8a%e9%80%8f%e6%98%8e%e6%95%88%e6%9e%9c/

◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()

數字轉換成字串
int count = 10;
Page.Response.Write( count.ToString() );
字串轉數字
String s = "10";
Page.Response.Write( int.Parse(s).ToString() );
格式化年月日
using System.Data.SqlClient;
DateTime dt = DateTime.Now;
DateLabel.Text = dt.ToString("yyy年MM月dd日");
重新導向網頁
Response.Redirect("rightArea.aspx");
開啟視窗
Literal txtMsg = new Literal();
txtMsg.Text += "<script>window.open('ctm07005_1.aspx?FirstDay=" + FirstDay + "&LastDay=" + LastDay + "','網路服務故障紀錄報表',";
txtMsg.Text += "'scrollbars=no,resizable=no')</script>";
Page.Controls.Add(txtMsg);
==(控制開啟頁重新載入)===========================
Literal txtMsg = new Literal();
txtMsg.Text = "<script>window.opener.location.reload(true);window.location='ctm01001_1.aspx?DNO=" + Request.QueryString["DNO"] + "';</script>
";
Page.Controls.Add(txtMsg);
驗證程式(驗證日期格式[2006/11/01])
using System.Text.Regularex<x>pressions;
bool IsValidDate(string strIn)
{
return Regex.IsMatch(strIn, @"^((([0-9]{2})|(((19)|([2]([0]{1})))([0-9]{2})))/(((0[1-9])|(1[0-2]))|([1-9]))/(((0[1-9])|([1-2][0-9])|(3[0-1]))|([1-9])))$");
}
驗證程式(是否是正確的email格式)
using System.Text.Regularex<x>pressions;
bool IsValidEmail(string strIn)
{
// Return true if strIn is in valid e-mail format.
return Regex.IsMatch(strIn, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
驗證程式(驗證資料中是否有數字)(有出現就可以)
String s = TextBox2.Text.ToString();
String p = @"^([0-9]+)";
if (Regex.IsMatch(s, p))
{
Response.Write("yes");
}
else
{
Response.Write("no");
}
驗證程式(驗證資料中是否有數字)(限制都是數字)
String s = TextBox2.Text.ToString();
String p = "^([0-9]+)$"; //或寫"^(\\d+)$"
if (Regex.IsMatch(s, p))
{
Response.Write("yes");
}
else
{
Response.Write("no");
}
驗證程式(驗證資料中是否是文字,含0~9,A-Z,a-z和_底線)
String s = TextBox2.Text.ToString();
String p = @"^(\w+)";
if (Regex.IsMatch(s, p))
{
Response.Write("yes");
}
else
{
Response.Write("no");
}
驗證程式(確定起始日期>結束日期,驗證日期欄位為正常的輸入)
if (String.Compare(UcFistDate.Value, UcLastDate.Value) > 0)
顯示訊息框
using System.Windows.Forms;
MessageBox.Show("訊息框內容","訊息框標題");
動態處理網頁中元件的語法(有Master頁時使用)
Label l1 = (Label)Master.FindControl("ContentPlaceHolder1").FindControl("Label1");
l1.Text = "hello";
動態處理網頁中元件的語法(無Master頁時使用)
TextBox t1 = (TextBox)this.FindControl("TextBox2");
t1.Text = "hello";
動態處理網頁中元件的語法(還需要研究的)
TextBox tb = (TextBox)PreviousPage.Master.FindControl("ContentPlaceHolder1").FindControl("TextBox1");
動態產生網頁中的元件
public partial class FlylonTest003 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.TextBox TextBox1;
protected System.Web.UI.WebControls.TextBox TextBox2;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Set the initial properties for the text boxes.
TextBox1.Text = "TextBox1";
TextBox2.Text = "TextBox2";
}
}
// 覆寫
override protected void OnInit(EventArgs e)
{
// Create dynamic controls here.
// Use "using System.Web.UI.WebControls;"
TextBox1 = new TextBox();
TextBox1.ID = "TextBox1";
TextBox1.Style["Position"] = "Absolute";
TextBox1.Style["Top"] = "25px";
TextBox1.Style["Left"] = "100px";
Form1.Controls.Add(TextBox1);
TextBox2 = new TextBox();
TextBox2.ID = "TextBox2";
TextBox2.Style["Position"] = "Absolute";
TextBox2.Style["Top"] = "60px";
TextBox2.Style["Left"] = "100px";
Form1.Controls.Add(TextBox2);
this.TextBox1.TextChanged += new System.EventHandler(this.TextBox_TextChanged);
this.TextBox2.TextChanged += new System.EventHandler(this.TextBox_TextChanged);
base.OnInit(e);
}
// 文字方塊的動作
private void TextBox_TextChanged(object sender, System.EventArgs e)
{
TextBox txtBoxSender = (TextBox)sender;
string strTextBoxID = txtBoxSender.ID;
switch (strTextBoxID)
{
case "TextBox1":
Label3.Text = "TextBox1 text was changed";
break;
case "TextBox2":
Label4.Text = "TextBox2 text was changed";
break;
}
}
}
直接對資料庫做查詢(Query)
using System.Data.SqlClient;
//取得文件編號
string strsql = "SELECT distinct AREANO FROM ctmBASE WHERE BASENO = '" + dlBASE.SelectedValue + "'";
SqlDataReader sqldr = ctmDBCONN.OpenSQL(strsql);
while (sqldr.Read())
tbDNO.Text = Convert.ToString(sqldr["BASENO"]));
tbDNO.Text += ctmDBCONN.GetDNO(Convert.ToString(sqldr["AREANO"]), "ctmTelApply", "1");
public static SqlDataReader OpenSQL(string strsql)
{
SqlConnection sqlconn = ctmDBCONN.getDBConn();
sqlconn.Open();
SqlCommand sqlcmd = new SqlCommand(strsql, sqlconn);
SqlDataReader sqldr = sqlcmd.ExecuteReader();
return sqldr;
}
==(另一種查詢方式)========================
string strsql = "select PLACE from ctmBASE where SBNO1='" + lbPLACE.Text + "'";
SqlConnection sqlconn = ctmDBCONN.getDBConn();
sqlconn.Open();
SqlCommand sqlcmd = new SqlCommand(strsql, sqlconn);
SqlDataReader sqldr = sqlcmd.ExecuteReader();
while (sqldr.Read())
tbDNO.Text = Convert.ToString(sqldr["BASENO"]));
直接對資料庫做新增(Insert)
// Check SBNO1 Value
string sSQL = "select SBNO1 from ctmBASE where PLACENO = '" + dlPLACE.SelectedValue + "'";
sqldr = ctmDBCONN.OpenSQL(sSQL);
sqldr.Read();
==(或)======================
// Insert DATA to DB
sdsTmp.InsertCommand = "INSERT INTO [ctmTelApply] ([DNO] , [APPLY_DT] , [BASE] , [SBNO1] , [PLACE] , [C_NAME] , [C_TEL] ) " +
"VALUES (@DNO , @APPLY_DT , @BASE , @SBNO1 , @PLACE , @C_NAME , @C_TEL )";
sdsTmp.InsertParameters.Clear();
sdsTmp.InsertParameters.Add("DNO", tbDNO.Text);
sdsTmp.InsertParameters.Add("APPLY_DT", ucAPPLY_DT.Value);
sdsTmp.InsertParameters.Add("BASE", dlBASE.SelectedItem.Text);
sdsTmp.InsertParameters.Add("SBNO1", Convert.ToString(sqldr["SBNO1"]));
sdsTmp.InsertParameters.Add("PLACE", dlPLACE.SelectedValue);
sdsTmp.InsertParameters.Add("C_NAME", tbC_NAME.Text);
sdsTmp.InsertParameters.Add("C_TEL", tbC_TEL.Text);
sdsTmp.Insert();
sdsTmp.DataBind();
DropListBox增加
DropListBox.Items.Add(new ListItem("標題", "預設值"));
NavigateUrl所代表的意思
就像傳統的連結網址出去一樣
直接對資料庫做查詢
string strsql = "SELECT Table1.ID AS ID FROM Table1";
SqlDataReader sqldr = ctmDBCONN.OpenSQL(strsql);
while(sqldr.Read()){
Response.write(sqldr["ID"].ToString());
}
DialogResult確認是否真的要刪除資料
using System.Windows.Forms;
//確認是否真的要刪除資料
DialogResult result = MessageBox.Show("確定要刪除嗎?", "系統訊息(刪除提醒)", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly);
if (result != DialogResult.OK) e.Cancel = true;
MessageBox.Show("刪除成功", "系統訊息", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
GridView裡有個RowDataBound事件
RowDataBound事件,是當我們讀資料進GridView時,GridView在讀取每一列資料時
所觸發的事件。透過這個方法,我們可以對特定的幾列做一些條件上的限制
// 控制特定的資料可以編輯,其他的不可編輯
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[0].Enabled = false;
if ((DataBinder.Eval(e.Row.DataItem, "C_NAME") != null) && (Page.Session["username"] != null))
if (DataBinder.Eval(e.Row.DataItem, "C_NAME").ToString() == Page.Session["username"].ToString())
e.Row.Cells[0].Enabled = true;
}
}
GridView裡有個RowDeleting事件
當刪除此列記錄時,會觸發的事件
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
if ( MessageBox.Show("確定要刪除此筆資料嗎?", "訊息對話窗", MessageBoxButtons.OKCancel, MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.OK) {
} else {
e.Cancel = true;
}
}
GridView,控制GridView中的RadioButton和TextBox
System.Web.UI.WebControls.RadioButtonList check = (System.Web.UI.WebControls.RadioButtonList)GridView1.Rows[i].Cells[0].Controls[0];
System.Web.UI.WebControls.TextBox mytxt = (System.Web.UI.WebControls.TextBox)GridView1.Rows[i].Cells[6].FindControl("txtReason");
GridView,取隱藏欄位的資料
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="SNO" runat="server" Value='<%# Eval("SNO") %>' />
</ItemTemplate>
</asp:TemplateField>
String SNO = ((System.Web.UI.WebControls.HiddenField)GridView1.Rows[e.RowIndex].Cells[7].FindControl("SNO")).Value;
GridView,設定顯示日期的格式
// HtmlEncode="false"一定要設,然後再指定DataFormatString就可以了
// DataFormatString="{0:yyy年MM月dd日}"
<asp:BoundField HtmlEncode="false" DataField="APPLY_DT" HeaderText="申請日期" Sortex<x>pression="APPLY_DT" DataFormatString="{0:yyy年MM月dd日}" />
GridView,取消刪除動作資料
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
e.Cancel=true;
}
GridView,取出查詢後的總筆數
DataView view = GridView1.DataSource as DataView;
int count = view.Table.Rows.Count;
sqlDataSource,直接讓SQL語法做查詢
sqldatasource.SelectCommand = "SELECT * FROM A"
sqldatasource.DataBind();
SqlDataSource,直接下指令要求DataSource執行更新動作
protected void SendApply_Click(object sender, EventArgs e)
{
((System.Web.UI.WebControls.TextBox)FormView1.FindControl("PROGRESS")).Text = "1";
ShowDetail.Update();
}
跳出視窗頁的處理(更新原來的主網頁,然後關閉此跳出視窗)
Literal txtMsg = new Literal();
txtMsg.Text = "<script>window.opener.location='ctm06002_1.aspx?DNO=" + DNO + "';</script>";
txtMsg.Text += "<script>window.close();</script>";
Page.Controls.Add(txtMsg);
整個框架頁都轉回到特定的某一頁
page.Server.Transfer("Login.aspx");
重新導向網頁
MessageBox.Show("系統偵測到您的登入資料未正確(或使用時間過長),\n\n請重新登入系統\n 謝謝~", "通航資系統錯誤訊息", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
Response.Redirect("Login.aspx");
控制網頁跳到Frame的最上層
Literal txtMsg = new Literal();
txtMsg.Text = "<script>top.location.href='default.aspx';</script>
";
Page.Controls.Add(txtMsg);
ja<x>vascript控制(畫面置中上面)
<script language="ja<x>vascript">
self.moveTo(screen.availWidth/2-239,0);
self.resizeTo(478,300);
</script>
永遠都會帶著框架
<script language="ja<x>vascript">
</script>
自已寫的基本驗證
// 驗證傳入的參數是否正確
if ((Session["username"] == null) || (Session["username"] == "") || (Session["username"] == "訪客"))
{
MessageBox.Show("系統偵測到您的登入資料未正確(或使用時間過長),\n\n請重新登入系統\n 謝謝~", "通航資系統錯誤訊息", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
Master.Response.Redirect("rightArea.aspx");
} else if ( (Request.QueryString["DNO"]==null) || ( Request.QueryString["DNO"]=="")) {
MessageBox.Show("未正確登入此網頁,將跳回", "通航資系統錯誤訊息", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
Master.Response.Redirect("rightArea.aspx");
} else if () {
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HTML控制項程式
(物件控制元件)---------------------------------------------------------
<html標籤 ID="物件名稱" Runat="Server">
</html>
控制處理(在aspx中)
<Script Language="VB" Runat="Server">
Sub Page_Load(ByVal Sender As Object, ByVal e As EventArgs)
物件名稱.Attributes("Text")="White"
物件名稱.Attributes("BgColor")="Black"
物件名稱.Attributes("href")="http://www.kimo.com.tw"
物件名稱.Attributes("Title")="連結到kimo網站"
End Sub
</Script>
InnerText
InnerHTML
Disabled
Visble
Value
(超連結控制元件)---------------------------------------------------------
控制處理(在aspx中)
<Script Language="VB" Runat="Server">
Sub Page_Load(ByVal Sender As Object, ByVal e As EventArgs)
物件名稱.Href="http://www.kimo.com.tw"
物件名稱.Target="_blank"
物件名稱.Title="按一下連結到kimo"
End Sub
</Script>
(圖片控制元件)---------------------------------------------------------
<Script Language="VB" Runat="Server">
Sub Page_Load(ByVal Sender As Object, ByVal e As EventArgs)
物件名稱.Src=""
物件名稱.Width=""
物件名稱.Height=""
物件名稱.Align=""
物件名稱.Border=""
物件名稱.Alt=""
End Sub
</Script>
(表單控制元件)(Form)---------------------------------------------------------
<Form ID="物件名稱" Runat="Server">
<Script Language="VB" Runat="Server">
Sub Page_Load(ByVal Sender As Object, ByVal e As EventArgs)
物件名稱.Action=""
物件名稱.method=""
End Sub
</Script>
(表單控制元件)(Button)---------------------------------------------------------
<Button ID="物件名稱" Runat="Server" OnServerClick="處理事件的副程式名稱">按鍵上的文字</Button>
<Script Language="VB" Runat="Server">
Sub Click_sub(ByVal Sender As Object, ByVal e As EventArgs)
End Sub
</Script>
(表單控制元件)(button,submit,reset)(Text,Password,Hidden))---------------------------------------------------------
<Input Type="按鍵類型(button,submit,reset)(Text,Password,Hidden)" ID="物件名稱" Runat="Server" OnServerClick="處理事件的副程式名稱" Value="按鍵上的文字">
<Script Language="VB" Runat="Server">
Sub Click_sub(ByVal Sender As Object, ByVal e As EventArgs)
Span1.InnerHtml="
資料已傳送到伺服端"
End Sub
</Script>
(表單控制元件)(Radio,CheckBox)---------------------------------------------------------
<Input Type="按鍵類型(Radio,CheckBox)" ID="物件名稱" Name="群組名稱" Runat="Server" Value="按鍵上的文字" Checked>
<Script Language="VB" Runat="Server">
Sub Click_sub(ByVal Sender As Object, ByVal e As EventArgs)
if 物件名稱.Checked then
end if
End Sub
</Script>
(表單控制元件)(TextArea)---------------------------------------------------------
<TextArea ID="" Runat="Server" Rows="列數" Cols="欄數" Wrap(自動換行)>顯示的內容</TextArea>
(表單控制元件)(Select)---------------------------------------------------------
<Select ID="物件名稱" Runat="Server" Size="選單的列數" Multiple>
<Option Value="傳回值" Selected>第一個選項字串</Option>
<Option Value="傳回值">第二個選項字串</Option>
</Select>
物件名稱.Items.Add("增加的內容")
物件名稱.Items.Remove("欲刪除的內容")
物件名稱.Items.Clear
物件名稱.Items.Count
物件名稱.Items(n).Selected 確定是第幾個被選取
<Script Language="VB" Runat="Server">
Sub Sub_sub(ByVal Sender As Object, ByVal e As EventArgs)
Dim X, I As Integer
X = SelName.Items.Count ' 把清單的總筆數指定給X變數
TextName.value=""
For I=0 to X-1 ' 設定從0至總筆數-1,以測試每一選項被選取
if SelName.Items(I).Selected then
TextName.value+=(SelName.Items(I).value & chr(13))
end if
next
End Sub
</Script>
本文引用網址:http://blog.csdn.net/xiaoxiaohai123/archive/2007/07/23/1703003.aspx

◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()


<html>
<head>
<script language="javascript">
function clear(){
    Source=document.body.firstChild.data;
    document.open();
    document.close();
    document.title="看不到源代碼";
    document.body.innerHTML=Source;
}
</script>
</head>
<body onload=clear()>


</body>
</html>


本文引用網址:http://blog.kidbook.com.tw/asaprogramer/article.asp?id=25

◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()


 

http://www.microsoft.com/downloads/details.aspx?FamilyID=8c4e8e0d-45d1-4d9b-b7c0-8430c1ac89ab&displaylang=zh-tw&Hash=0h9MHLtjxpDctPIl2K23%2fsXqzpNJcOPF1nNWZjMPUnVHqw%2fmsRkV02bcYV66CujSRNn6Uv8i8Kw4EHh%2bj8Xbyg%3d%3d

簡述

不必變更非 Unicode 應用程式的語言 (系統地區設定) 就可以執行舊版應用程式。


概觀


以 Unicode 為基礎的平台 (例如 Windows XP) 會模擬執行非 Unicode 應用程式所需要的語言環境,模擬的方式是在內部使用一般稱為系統地區設定的系統變數 (或是非 Unicode 應用程式的語言),將應用程式的非 Unicode 文字資料轉換成 Unicode。非 Unicode 應用程式的語言與系統地區設定所定義的語言,應該是使用相同的指令碼或指令碼系列。如果不符合這個條件,應用程式的使用者介面 (UI) 就會顯示成亂碼。
這種方式在使用上有一些限制:

  • 只有系統管理員可以設定系統地區設定的值。
  • 設定系統地區設定時必須重新啟動系統。
  • 一次只能設定一個系統地區設定。

AppLocale (或 Application Locale) 只能暫時解決這些在以 Unicode (UTF-16) 為基礎的 Windows XP 系統中執行非 Unicode 應用程式的限制。AppLocale 會偵測舊版應用程式的語言,並且模擬對應的系統地區設定,以便在字碼頁與 Unicode 之間進行轉換。
重要注意事項:

  • AppLocale 是以 Windows XP 中所引用的最新應用程式相容性技術為基礎,因此只能安裝在這兩種作業系統中。
  • 如果您經常在特定指令碼 (或一組語言) 中使用非 Unicode 應用程式,建議您一定要將系統地區設定變數設定為目標應用程式的語言,而不要使用 AppLocale。
  • 應用程式的開發人員不可以將 AppLocale 當作產品移轉為 Unicode 的替代方式。目前,已經可以使用 Microsoft Layer for Unicode (MSLU) 建立純正的 Unicode 應用程式,而且也可以部署在非 Unicode 的平台上 (例如 Windows 98) 。

系統需求




  • 支援的作業系統: Windows Server 2003; Windows XP


  • 已經安裝語言支援。

AppLocale 可以在英文版及中文版的 Windows XP 或 Windows Server 2003 系統中執行,但是使用者介面是英文的,不會翻譯成中文。

 

◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()

如同大家所知,在 HTML 檔中呼叫 .js 檔的語法有兩種:
一種是呼叫存放在主機內的 .js 檔,語法是<script src="exter.js"></script>
另一種是連結呼叫存放在不同主機內的 .js 檔到網頁中執行,語法和上述的相同,只是連結位址更改而已,
<script src="http://www.othersite.com/exter.js"></script>
哇!我是不是有可能將盜連別人網站程式的語法寫出來了?搞不好本來有人不知道的,這下反而被包子提醒了;不過也可能有某些網站的程式早就被盜連,只是站長不知道而已。很多人要緊張擔心了,程式被盜連可能還不算太慘,糟糕的是因為被盜連而可能產生的大量傳輸,拖慢了網站瀏覽的速度。雖然 .js 檔平均來講不佔多少空間,其實沒有盜連的必要;但是當你覺得需要保障的時候,以下的語法就很重要了。
因為可以由其他網站呼叫你的 .js 程式,所以我們可以寫一段 JavaScript 插入在需要被保護的 .js 檔的最上方,設定哪一個或哪幾個網址可以直接連結你的 .js 程式,其他的不行。
讓我們來看看程式:


  1. var accepted_domains=new Array("run.to/java168","kimo.com.tw")
  2. //設定只有 run.to/java168 和 kimo.com.tw 這兩個網站可以直接連結這組程式
  3. //你也可以改成"",表示不允許其他任何網站連結這組程式

  4. var domaincheck=document.location.href //偵測瀏覽器目前的網頁位址
  5. var accepted_ok=false

  6. if (domaincheck.indexOf("http")!=-1){
  7. for (r=0;r if (domaincheck.indexOf(accepted_domains[r])!=-1){
  8. accepted_ok=true
  9. break
  10. }
  11. }
  12. }
  13. else
  14. accepted_ok=true

  15. if (!accepted_ok){
  16. alert("此站站長未經允許擅自盜連這組程式!") //在該盜連網頁上跳出警告小視窗
  17. history.back(-1) //強制回到前一頁
  18. }

  19. //以下才是原 .js 檔的程式內容開始
  20. .......................
  21. .......................


 

◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()

說真的,「滑鼠移過表格變色」或是「滑鼠移動列變色」這種概念實在是很難用中文來表達,當初為了找這種「變色」的相關程式碼,實在是花了不少直角不少功夫,用英文來找的話,就顯得簡單多了,英文的關鍵字為「change row color on mouseover」。
如果還是不曉得直角在說什麼的話,請直接看本文範例
為了達到表格列(row)變色之目的,只要在表格中 <tr> 的標籤內加入以下的程式碼即可:
<tr bgcolor="#顏色" onmouseover="this.style.backgroundColor='#顏色';" onMouseOut="this.style.backgroundColor='#顏色';">
onMouseOver 的屬性為滑鼠移動時的顏色, 至於 onMouseOut 的屬性為滑鼠移走後之顏色,若不設定時,則為 <tr> 原本的背景色(bgcolor)。
站範例為使用 Javascript 所達到的技術,不論在 Firefox 或 IE 上皆可正常執行,可參考以下網址取得相關資訊:
  • Manuel Viloria - Change Table's Background Color (onmouseover)
    http://www.viloria.com/secondthoughts/archives/00000371.html

  • Linux User
    http://www.linuxuser.com.tw/power/list2.php?id=646

  • 至於使用 CSS 之範例,各位網友們可以參考下列資料,不過畢竟直角還沒有試過,因此僅供參考:
  • episode - 網頁建置百寶箱 - 表格之變色
    http://dob.tnc.edu.tw/themes/old/showPage.php?s=371&t=2

  • 辣辣箭 - 表格顏色交替變色CSS效果
    http://blog.cuiz.net/article.asp?id=63

  • 本文引用網址:http://mrangle.macroviz.com/?p=90

    ◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()


    雖然VS 2008已經內建 AJAX,但是微軟有蒐集許多好用的AJAX控制項,包裝起來,分享給大家。

    但是,這個AJAX Control Toolkit 該怎麼安裝到我的VS 2008裡面呢?

     

     

    1.  首先,下載軟體。http://www.codeplex.com/AjaxControlToolkit/Release/ProjectReleases.aspx?ReleaseId=16488

    建議下載 [完整版](最上面的第一個,檔案容量3033K)

     

    2.  然後,解開壓縮。

    我會建議把解壓縮之後的完整目錄,COPY到 C:\Program files目錄下,比較不會被誤刪。

    目前存放的目錄名稱為   C:\Program files\AjaxControlToolkit-Framework3.5SP1

     

    3.  打開您的 VS 2008,強烈建議已經升級到 SP1。

    在右邊的「工具箱」,按下「滑鼠右鍵」,加入「索引標籤」。

    以我為例,輸入「AJAX Control Toolkit 3.5」。

     

    4.  再來一次,在右邊的「工具箱」,按下「滑鼠右鍵」,選取「選擇項目」。

    這動作比較耗時,要耐心等一下。........完成後,會看見下面的畫面。


     

    5.  到剛剛解壓縮的 C:\Program files\AjaxControlToolkit-Framework3.5SP1 目錄底下

    WebSites\Bin目錄,有一個 Ajaxcontroltoolkit.DLL檔

    完成後,就OK啦!

    看下圖,已經出現 AJAX的控制項囉!


     

    完成上面步驟,就OK啦。

    我的VS 2008,已經多了 AJAX Control Toolkit 3.5 (SP1版)。


     本文引用網址:http://www.cnblogs.com/yjg8116/archive/2008/12/05/1348102.html

    ◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()


    關於工具提示(Tooltip),或者說網頁上的浮動附加說明效果,最常見的作法大概是以JavaScriptJQuery來做。

    大約在兩年前,曾有一陣子很流行自製網站連結預覽,無論是自己去抓特製的浮動預覽JS(*.js, JavaScript)語法來用,或者直接使用Snap Shots™這一類連結預覽服務網站所提供的語法,運作邏輯大抵上都不出JavaScript或jQuery的範圍。

    然而,JavaScript或jQuery雖然好用,但,就我個人實作的心得,仍不免會有以下幾點疑慮:


    1. 耗資源
    2. 或多或少拖慢網頁載入速度
    3. 不同瀏覽器及版本的效果與衍生的問題不一
    4. 有可能產生程式衝碼

    因此,大概只使用了一年就決定放棄,轉而思考以純CSS的作法來達到相彷的效果。

    理論上,以純CSS來完成浮動工具提示,似乎只要在「display」的宣告參數上,應用「none」及「block」來切換浮動訊息的顯示與否,配合絕對定位position:absolute的「z-index」參數宣告,最後再以「a」及「a:hover」來觸發浮動工具提示,應該就大功告成。

    不過,真正實作起來,還是費了一番功夫,才總算調校測試完成。

    幾天前,我在這篇文章開始試用這個「純CSS浮動工具提示」的作法,效果似乎還不錯:

    最起碼,不會再有耗資源、拖慢網頁速度、瀏覽器效果不一,以及程式衝碼的問題。

    以下整理「純CSS浮動工具提示」的作法:

    首先,是CSS的宣告部份:/* Jas's CSS ToolTip */
    a.jastips{
    z-index:9;
    color:#690;
    border-bottom:1px dotted #690;
    text-decoration:none;
    }
    a.jastips:hover{
    position:relative;
    z-index:99;
    cursor:help;
    }
    a.jastips span{
    display:none;
    }
    a.jastips:hover span{
    display:block;
    position:absolute;
    float:left;
    white-space:nowrap;
    top:-2.25em;
    left:0;
    background:#666;
    border:1px solid #000;
    color:#fff;
    padding:1px 5px;
    margin:0;
    z-index:9;
    }
    /* end of Jas's CSS ToolTip */

    其次,是HTML的應用部份:<a href="#" class="jastips">在這裡輸入需要說明的關鍵字<span>在這裡輸入預定顯示在浮動工具提示的說明文字</span></a>

    以上述說明為例,最後應用的效果如右所示:在這裡輸入需要說明的關鍵字在這裡輸入預定顯示在浮動工具提示的說明文字

    其實CSS能玩的花樣很多,這裡所整理出來的只是最實用的基本款,我相信循著相彷的運作邏輯,巧妙運用創意,應該還能變出各種千奇百怪的效果跟應用才對。

    本文引用網址http://www.haloscan.com/tb/jas9/4757241835316636565/;http://jas9.blogspot.com/2008/06/css.html

    ◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()


     

    週日晚看偶像劇時,

    只因一幕景物,勾起三年前的回憶.....

    弟在此時說"看到東方明珠電視塔......."

    我輕斥一聲"別再往下說!"

    是的,弟看到了

    也同不其然的想起你

     

    三年多了.....一千多個日子.....

    那時站在高處時,你心裡可曾想到什麼?想到誰?

    當你蹤身前,又看到什麼?

    你是家族的驕傲,好優秀的你

    一直無法相信那人是你

    甕中白白灰灰是你嗎?

    新聞中報導的人是你嗎?

    真的是你嗎?真的是你嗎?

    若不是你,你又在何處呢?

     

    三年過去了.....一千多個日子過去了.....

    沒人忘記你,始終掛念你.......

    但又能如何

    已喚不回隨風而輕揚的你

     

    想輕問一句

    在另一個世界的你,你好嗎?

    自在嗎?快樂嗎?

     

    ◕‿◕ Abigale 發表在 痞客邦 留言(1) 人氣()

    1 2
    Blog Stats
    ⚠️

    成人內容提醒

    本部落格內容僅限年滿十八歲者瀏覽。
    若您未滿十八歲,請立即離開。

    已滿十八歲者,亦請勿將內容提供給未成年人士。