Showing posts with label .NET. Show all posts

使用JQuery autocomplete 一次完成多個欄位填寫

假設我有三個欄位,分別是姓名、電話、住址。我想在輸入姓名的時候用autocomplete去撈出資料庫中的姓名,選好後三個欄位都幫我填入所屬該姓名的資料。

在web service部分我把要回傳的值用';'來區別。

<%@ WebHandler Language="VB" Class="TeacherCo" %>

Imports System
Imports System.Web
Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Text

Public Class TeacherCo : Implements IHttpHandler

Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim prefixText As String = context.Request.QueryString("q")
Dim conn As SqlConnection = New SqlConnection
conn.ConnectionString = ConfigurationManager.ConnectionStrings("AAA").ConnectionString
Dim cmd As SqlCommand = New SqlCommand
cmd.CommandText = ("SELECT 姓名,電話,住址 FROM 資料表 WHERE " & _
"姓名 like @SearchText + '%'")
cmd.Parameters.AddWithValue("@SearchText", prefixText)
cmd.Connection = conn
Dim sb As StringBuilder = New StringBuilder
conn.Open()
Dim sdr As SqlDataReader = cmd.ExecuteReader
While sdr.Read
sb.Append(sdr(0) & ";" & sdr(1) & ";" sdr(2)).Append(Environment.NewLine)
End While
conn.Close()
context.Response.Write(sb.ToString)

End Sub

Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property

End Class


前端網頁處理

$(document).ready(function() {
//auto complete
$("#姓名").autocomplete('TeacherCo.ashx', {
scrollHeight: 220,
formatItem: function(data, i, total) {
var StrAndNum = data[0].split(';');
return StrAndNum[0];
},
formatResult: function(data) {
var StrAndNum = data[0].split(';');
return StrAndNum[0];
}

});
$("#姓名").result(function(event, data, formatted){
var StrAndNum = data[0].split(';');
if (StrAndNum[1] != null){
$("#電話").val(StrAndNum[1]); $("#住址").val(StrAndNum[2]);

}else{
$("#電話").val('');$("#住址").val('');
}
});

TreeView 資料庫子母節點

In this case , I use MSSQL to save my TreeView node, and recursive loop nodes.
在新的專案中,我將TreeView獨立出成usercontrol並用viewstate去記錄節點的開合狀態,然後放在masterpager中。而TreeView的節點是從資料庫撈取,資料庫的表格大致如下:


撈節點的方式是先建立根節點(判斷Level0是否為true) 然後再用遞迴的方式去新增....
中間再加入一個條件去判斷該使用者是否有該節點的ID值,有就新增。

'主架構
Public Sub BuildTree()

Dim dst As DataSet = GetTreeViewData() '從資料庫把Table撈出來丟到dst
Session("Dt") = dst.Tables("eip_power_tree")

For Each masterRow As DataRow In dst.Tables("eip_power_tree").Rows

If masterRow("Level0") = True Then 'build Root Node
Dim masterNode As New TreeNode(masterRow("ID"), masterRow("ID"))
TreeView1.Nodes.Add(masterNode)
'呼叫建立子節點的函數
AddNodes(masterNode, masterRow("ID"))
End If

Next

End Sub

Function AddNodes(ByRef tNode As TreeNode, ByVal PId As Integer) As String
'******** 遞迴增加樹結構節點 ********
Try

'定義DataTable
Dim Dt As DataTable
'從Session中取得DataTable
Dt = Session("Dt")

'定義DataRow承接DataTable篩選的結果
Dim rows() As DataRow
'定義篩選的條件
Dim filterExpr As String
filterExpr = "UpLevel_id = '" & PId & "'"
'資料篩選並把結果傳入Rows
rows = Dt.Select(filterExpr)

'如果篩選結果有資料
If rows.GetUpperBound(0) >= 0 Then
Dim row As DataRow
Dim tmpNodeId As Long
Dim NewNode As TreeNode


'逐筆取出篩選後資料
For Each row In rows
'和權限table比對
If powerDt.Select("power_tree_ID='" & row(0) & "'").Length > 0 Then
'放入相關變數中
tmpNodeId = row(0)

'實體化新節點
NewNode = New TreeNode
'設定節點各屬性
NewNode.Text = IIf(IsDBNull(row(1)), "", row(1))
NewNode.Value = IIf(IsDBNull(row(6)), "", row(6))
'NewNode.NavigateUrl = tmpsUrl
'NewNode.Target = tmpsTarget
'將節點加入Tree中
tNode.ChildNodes.Add(NewNode)

'呼叫遞回取得子節點
AddNodes(NewNode, tmpNodeId)
End If
Next
End If
Catch ex As Exception
Throw ex
End Try
Return True
End Function



DataList, Repeater 產生大量空白....

平常coding的時候都會稍微做個註解方便之後維護,這次做表格的時候也不例外,因為表格內容很複雜,所以註解也特別多,結果在DataBind的時候,資料都有出來,但是就是硬生生的會多出很大一片的空白,不管是用Datalist還是Repeater都有相同的情況!! 一開始還以為資料綁定的方式錯誤,或是Viewstate的影響,查了GOOGLE也發現有問題的人不多....提供的方式也無效....
最後氣到,乾脆把所有的註解都拿掉!
........結果就好了....... 0rz

真不曉得為什麼不可以在ItemTemplate裡面用 mark 標籤......
(blank screen when binding Datalist,Repeater )
Remove <! - - ... - -> tag if you have problem in blank screen when binding Datalist or  Repeater. 

JQuery & .Net區塊的拖拉&存取

JQuery&.Net droppable and save.
因為工作上需要把舊有的網頁改版,改成使用者可以自訂想要區塊的選擇方式,在.NET開發的選擇上可使用webpart的方式來達成,但個人認為webpart的前置作業會過於繁瑣...

我的作法是當使用者讀取首頁的時候,使用PlaceHolder的方式把包好不同功能的使用者自訂項(.ascx)丟進去,那至於使用者要如何設定要的區塊呈現,則是另外用一個頁面使用Jquery的droppable的方法來拖拉DIV,並儲存區塊間的順序到資料庫.....


-----------------------------------------------------------------
流程:
1. page load的時候從DB讀取該使用者的設定(若無則給予預設值),並將設定值放在input hidden裡面讓前端jquery讀的到(hid_restrict, hidden1,hidden2 分別為預設該權限禁止區塊、左邊區塊值、右邊區塊值)

2. 前端將區塊開始分類:先讀hid_restrict把禁止讀取的區塊拿掉,然後再依序讀取L1與R1,並把區塊放進去。
$(document).ready(function() {
//Restrict Area
var hid_rest = document.getElementById("Hid_restrict");
if (hid_rest.value.length > 0) {
var strRest = hid_rest.value.split(",");
for (var key in strRest) {
if (strRest[key].length > 0) {
$('#allCourse > div').filter('#' + strRest[key]).remove();
}
}
}
//Left side value左邊區塊
var hid1 = document.getElementById("Hidden1");

if (hid1.value.length > 0) {
var strL1 = hid1.value.split(",");
for (var key in strL1) {
if (strL1[key].length > 0) {
$('#L1').append('

' + getCode(strL1[key]) + '

');
//remove div from allCouse
$('#allCourse > div').filter('#' + strL1[key]).remove();
}
}
}
//Right side value右邊區塊
var hid2 = document.getElementById("Hidden2");

if (hid2.value.length > 0) {
var strR1 = hid2.value.split(",");
for (var key in strR1) {
if (strR1[key].length > 0) {
$('#R1').append('

' + getCode(strR1[key]) + '

');
//remove div from allCouse
$('#allCourse > div').filter('#' + strR1[key]).remove();
}
}
}


});
3.當使用者拖拉完後按下儲存按鈕,利用javascript把L1和R1區域內的區塊值再存回hidden1和hidden2, 並且用一個LinkButton當觸發條件回傳至後端
function save() {
var element_left = $('#L1 > .block');
var element_right = $('#R1 > .block');
var val1 = '';
var val2 = '';
for (var i = 0; i < element_left.length; i++) {
val1 += element_left[i].id + ",";
}
document.getElementById("Hidden1").value = val1;
for (var i = 0; i < element_right.length; i++) {
val2 += element_right[i].id + ",";
}
document.getElementById("Hidden2").value = val2;
__doPostBack('LinkButton1', '');

}
Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
'這邊放DB Insert String, 將Hidden1 Hidden2的值存入資料庫
End Sub

DataList & Jquery 分頁功能與全選 checkbox , PART 2

接下來討論怎麼利用前端Jquery去接使用者select all 和判斷哪個checkbox被選擇 ,在程式中我利用class的方式去判別需要用到的control:

  1. 首先加入Jquery和需要用到的Javascript:

  2. $(window).bind('load', function() {
    //全選的Button
    var headerChk = $(".chkHeader");
    //datalist 中的 checkbox
    var itemChk = $(".checkItem input");
    headerChk.bind("click", function() {
    itemChk.each(function() {
    this.checked = true;
    })
    });
    itemChk.bind("click", function() {
    if ($(this).checked == false) {
    //這邊放uncheck
    }
    });
    });
    //撈使用者勾選的項目並處理
    function SendToSMS() {
    var itemChk = $(".checkItem input[type=checkbox]:checked");
    var SMSstr = '';
    //每個選擇的項目
    itemChk.each(function() {

    var LB = $(this).attr('id');
    LB = LB.replace('CheckBox1', 'Label2');
    SMSstr += ',' + document.getElementById(LB).innerText;
    })
    if (SMSstr.length > 0) {alert(SMSstr);}

    }
  3. 然後在.aspx頁面中的Datalist:
  4.  















DataList & Jquery 分頁功能與全選 checkbox , PART 1

Using Pager Control(kevnord) & jquery for DataList in pager & select all checkbox.


在最近的工作上,碰到需要用DataList分頁的功能,但一旦將Datalist分頁後,會造成原來datalist中的checkbox 在使用postback的方式去全選的功能發生錯誤,於是不得不改用Jquery在前端處理checkbox的狀態....雖然會比原來用codebehide的方式複雜,但好處是可以減少postback增加整體效率! 先介紹怎樣使用 kevnord的Pager Control來讓DataList分頁,他是利用PageDataSource 這個類別去完成的.
  • Step1 : 在Visual Studio中將CollectionPager.dll加入.net Framework元件後拉到設計視窗內。在CodeBehide的地方設定Datasource, 因為我是用Sqldatasource, 所以我會先轉成Dataview再丟給CollectionPager :





Sub BindDT(ByVal sqlstr As String)
SqlDataSource1.SelectCommand = sqlstr
SqlDataSource1.DataBind()
ViewState("sqlstr") = sqlstr
CollectionPager2.DataSource = CType(SqlDataSource1.Select(New System.Web.UI.DataSourceSelectArguments), Data.DataView)
CollectionPager2.BindToControl = DataList1
CollectionPager2.Visible = True
DataList1.DataSource = CollectionPager2.DataSourcePaged
DataList1.DataBind()
End Sub
  • 然後在Page_load的地方去呼叫BindDT:
If IsPostBack = True And ViewState("sqlstr") <> Nothing Then

BindDT(ViewState("sqlstr"))

End If
  • OK, 大功告成! 如果需要再DataList上下各放一個Pager, 則再多用一個LITERAL Control複製原來的Pager:
    • 前端:


    • 後端:
      Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
              litTopPager.Text = CollectionPager2.RenderedHtml
              MyBase.Render(writer)
      End Sub

DataList 加入列印斷頁符號

一般來說Datalist Control並沒有可分頁的選項, 特別是在要印出來的時候如果沒有很好的分頁很容易造成美觀上的問題. 透過CSS的page-break-after (or before) 可以讓browser列印輸出讀到該行時斷頁.

假設我的Datalist 有兩個columns :
<asp:datalist &nbsp;repeatdirection="Horizontal" cellpadding="4" id="DataList1" 
repeatcolumns="2" runat="server"></asp:datalist>


我要在每列印六個row後進行分頁, 在DataList1_ItemDataBound中加入:

If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim sp As New Literal
sp.Text = "</td><tr><td colspan='2'><div style='page-break-after:always'></div></td></tr><tr><td colspan='2'>"
If e.Item.ItemIndex = 11 Or e.Item.ItemIndex = 23 Or e.Item.ItemIndex = 35 Then
e.Item.Controls.Add(sp)
End If
End If
OK, 到這邊基本上分頁斷行就加入完成了, 但是我列印的時候只想列印DataList的部分, 所以我又加了一段javascript程式碼:

<script language="javascript">
function PrintDataList(StrID) {

var prtContent = document.getElementById(StrID);
var WinPrint = window.open('', '', 'left=0,top=0,width=800,height=400,toolbar=no,scrollbars=auto,status=0');
WinPrint.document.write(prtContent.innerHTML);
WinPrint.document.close();
WinPrint.focus();
WinPrint.print();
WinPrint.close();

}
</script>
加個列印的Button把Datalist的clientID丟入就可以了!

[.net]DirectCast Vs. CType 哪種好?

文章轉自: CodeProject

DirectCast 不會將 Visual Basic 執行階段 Helper 常式用於轉換,因此在資料型別 Object 間進行轉換時,它可提供的效能比 CType 還好。

使用 DirectCast 關鍵字的方式與使用 CType 函式TryCast 關鍵字的方式相同。提供運算式做為第一個引數,並提供型別以將它轉換成第二個引數。DirectCast 需要這兩個引數之資料型別之間的繼承或實作關聯性。這表示其中一個型別必須繼承自另一個型別或實作另一個型別。


Introduction

When should you use CType and when should you use DirectCast and which one preforms better? The short answer is: DirectCast is twice as fast for value types (integers...etc), but identical for reference types.

Background

The first thing to understand is that CType and DirectCast are not the same thing. Only CType can convert the underlying object to a new instance of an object of a different type. For example, if you want to turn an integer into a string. Since an Integer doesn't inherit a String, a new instance of a String object must be created in order to store the number as a String. CType can do this, DirectCast cannot. Note: There are other ways to do this too such as the Convert.ToString method or CStr().

Dim MyInt As Integer = 123

Dim MyString1 As String = CType(MyInt, String)

Dim MyString2 As String = DirectCast(MyInt, String) ' This will not work

What DirectCast and CType do have in common is their ability to convert an object to a new type based on inheritance or implementation. For example, if you have a String but it is stored in a variable of type Object, you can use DirectCast or CType to treat that variable as an object of type String because type String inherits type Object. In this case, the underlying data in memory is not actually changing, nor is any processing happening on that data.

Dim MyObject As Object = "Hello World"

Dim MyString1 As String = CType(MyObject, String)

Dim MyString2 As String = DirectCast(MyObject, String) ' This will work

The danger: You MUST know what type you are dealing with before using DirectCast. If you have a variable of type Object and you use DirectCast to treat it as a String, you'd better be sure that variable actually contains a String (or Nothing). If an Integer somehow found its way into that variable an exception will be thrown.

A way to check in code if DirectCast will work is by using the TypeOf operator:

If TypeOf MyObject Is String Then

So, assuming you are doing a conversion based on inheritance or implementation, you have a choice: DirectCast vs. CType. Which is better?

The Answer

DirectCast. According to the .NET documentation: DirectCast does not use the Visual Basic run-time helper routines for conversion, so it can provide somewhat better performance than CType.
The included project runs a performance test on each scenario: DirectCast vs. CType for value and reference types. Remember, Reference types are types like Forms, Controls, Strings and custom classes whereas Value types are types like Integers, Doubles and custom structures. Here are the results; numbers are in milliseconds for 1 million iterations:

DirectCast on a reference type:

8.7885

CType on a reference type

11.718

DirectCast on a value type

18.5535

CType on a value type

39.06

The verdict: DirectCast out performs CType for value types almost 2 to 1. DirectCast also out preforms CType for reference types albeit by a much slimmer margin.
Note: Subsequent tests produced very similar results; try for yourself.
Another reason to use DirectCast is that it's not VB.NET specific and is therefore more portable to other languages. So C#...etc programmers might have an easier time reading your code if they encountered DirectCast.

[.NET] 使用保留字當型別

當型別宣告時的物件變數,您可以使用保留的關鍵字 ; 不過,這種作法應予以避免。如果 [環境] 設定 「 自動進行語法檢查"亮就會收到時發生錯誤"期望: 新增] 或 [型別名稱 」 或 「 需要: 型別名稱 」 取決於 [新增] 關鍵字的變數的宣告是否。

您 可以放置方括弧 ([]) 周圍保留的關鍵字來解決語法檢查 ; 請不過,Visual Basic 會從程式碼] 視窗移除方括號。因此,編輯有方括號的程式碼任何的行部分會導致程式碼語法檢查一次失效。此外,如果您儲存專案並在稍後重新載入它,然後嘗試執行此程式, 您會收到 「 錯誤 」 語法錯誤 」,直到您將新增回方括號。

[.NET] 關於 My 命名空間


使用 My 進行開發