程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 用ASP.NET在同一網頁中顯示主從關系表的相關數據

用ASP.NET在同一網頁中顯示主從關系表的相關數據

編輯:.NET實例教程
摘要:
  DataSet是數據集在內存中的表示方法,數據集可以有主從關系的數據表,在Access中這種關系表現的很直觀,本文討論在同一網頁上直觀地顯示有主從關系的相應數據的程序設計和程序。
  
  --------------------------------------------------------------------------------
  
  目錄
  方法
  Tables和ImageButtons的ID的命名規則
  網頁上Table的字段長度的估計
  主要程序
  事件過程
  應用實例
  
  --------------------------------------------------------------------------------
  
  方法 :
  對DataSet中的每一張表,如果有子表,將這張表的字段名行和每一紀錄行在網頁上都顯示為只有一行的Table,並在記錄行Table的第一列置上一個ImageButton,以便程序控制展開或關閉相應的子表的紀錄行所形成的Table或Tables。對於每一紀錄行,子表有相應的記錄行,若子表還有子表,則對子表重復上述過程,即將子表的字段名行與相應的記錄行在網頁上都顯示為只有一行的Table,並在記錄行Table的第二列置上一個ImageButton,反之將子表的字段名行與相應的紀錄行在網頁上顯示為一個Table。利用Table的Visible屬性,可以控制子表相應記錄行的顯示。顯然可以使用遞歸調用實現這一過程。
  
  --------------------------------------------------------------------------------
  
  Tables和ImageButtons的ID的命名規則:
  用對ImageButton的點擊,程序控制網頁上的相應的Tables的顯示與隱藏,這些ImageButton.id和Table.id的命名就需要一定的規則。
  對DataSet中的第一張主表:
  由字段行生成的網頁Table的id命名為t0
  由記錄行生成的網頁Tables的id分別為t1,t2,...tn ,與這些Tables相對應的ImageButton.id命名為 e1,e2,...en, 這裡 n:主表的記錄行數
  對DataSet中的子表:
  子表中的記錄行都是隸屬於主表中的某一記錄行,因此這些記錄行生成的網頁Tables也隸屬於主表某一記錄行所生成網頁的Table,如隸屬於t2的Tables命名為t2-0,t2-1,t2-3...,其中t2-0為子表的字段名行在網頁上生成的Table.id名,其余以此類推,若子表沒有子表了,即最後一個子表,則t2-0是包含子表的字段名行和相應的子表記錄行在網頁上生成的Table.id名。
  與這些table.id相對應的ImageButton.id分別命名為e2-1,e2-2,...。
  
  --------------------------------------------------------------------------------
  
  網頁上Table的字段長度的估計:
  DataSet中的每一張表都會在網頁上生成一些Table,這些Tables的外在形式應該是相同的。即Tables的相同的Cell應有同樣的長度。函數子程序SetCellSize計算DataTable的每一字段平均字符數,和字段名的字符數,並取其大者,若字段的某一紀錄或字段名都是ASCII字符,則其字符數減半。用此數據便可估計網頁上的Table的相應字段的顯示長度。
  下面是SetCellSize的程序,容易理解。
   Function SetCellSize(myTable as DataTable)
  dim myRow as DataRow
  dim i,j,k,m as integer
  dim aa() as integer
  dim myBool as Boolean
  
  m=myTable.columns.count-1
  redim aa(m)
  for i=0 to m
   aa(i)=0
  next
  
  for each myRow in myTable.rows '計算每一字段的平均字符長度
   for i=0 to myTable.columns.count-1
   dim mystr as string
   mystr=myRow(myTable.columns(i)).tostring
   j=len(mystr)
   if j>0 then
   myBool=true
   for k=1 to j '判斷dataTable中的每一項是否包括漢字
   dim str1 as char=mid(mystr,k,1)
   if ascw(str1)>255 then '有非ASCII字符
   myBool=false
   exit for
   end if
   next
   if myBool then j=(j/2+0.5) '都是ASCII字符,字符串長度減半
   aa(i)+=j
   end if
   next
  next myRow
  
  k=myTable.rows.count
  for i=0 to m
   aa(i)=aa(i)/k 'DataTable的每一列的平均長度
  next
  
  for i=0 to myTable.columns.count-1 '對每一字段名
   dim str2 as string=myTable.columns(i).columnname
  
   j=len(str2)
   if j>0 then
   myBool=true
   for k=1 to j '判斷字段名中是否包括漢字
   dim str1 as char=mid(str2,k,1)
   if ascw(str1)>255 then '有非ASCII字符
   myBool=false
   exit for
   end if
   next
   if myBool then j=(j/2+0.5) 'ASCII字符,字符串長度減半
   if j>aa(i) then aa(i)=j
   end if
  next
  SetCellSize=aa
  end Function
  
  
  
  
  --------------------------------------------------------------------------------
  
  主要程序:
  子程序ShowTables設置一些初始值,然後調用子程序ShowChildRows。
  子程序ShowChildRows的參數說明:
  Rows:是一個DataRow數組,第一次調用ShowChildRows時,是DataTable的所有的記錄行。以後遞歸調用ShowChildRows時,是與父表某一記錄行相關的子表的一些記錄行。
  myTable:Rows所屬的DataTable,程序將使用它的Columns,即字段名行。
  aa:函數子程序SetCellSize返回的一維整型數組。
  spaces:整型參數,用於在網頁顯示Tables時,這些Tables左側應設置幾個空單元格,以顯示Table的隸屬關系。
  signal:字符串參數,ImageButton的id值,用於生成相關的Tables和ImageButtons的id。
  因為要在網頁中添加Table控件,所以在網頁中應有一個id為form1的Form控件。
  動態地創建一個Table有三個步驟,首先,創建 TableCell 對象,即行中的單元格,添加單元格的內容有兩種方法:設置 Text 屬性,或者向 TableCell 的 Control.Controls 集合添加控件,程序中對某些單元格添加ImageButton控件;接下來,創建 TableRow 以表示表中的行,將此前創建的 TableCell 對象添加到 TableRow 的 Cells 集合中。最後,將 TableRow 添加到 Table 控件的 Rows 集合中。
  以下是程序:
   Sub ShowTables(mySet as DataSet)
  dim spaces as integer=0
  dim aa() asinteger
  dim i,d as integer
  dim signal as string=""
  
  dim myTable as dataTable=mySet.tables(0)
  dim rows() as DataRow
  d=myTable.rows.count-1
  redim rows(d)
  
  
  for i=0 to myTable.rows.count-1
   rows(i)=myTable.rows(i)
  next
  
  aa=SetCellSize(myTable)
  Call ShowChildRows(rows,aa,myTable,spaces,signal)
  End Sub
  
  
  
   Sub ShowChildRows(rows() as DataRow,aa() as integer,myTable as DataTable,spaces as integer,signal as string)
  dim i,j,k,m,leng as integer
  dim fontsize as integer=10
  
  dim myRow as DataRow
  dim myCol as DataColumn
  
  dim testTable as Table
  
  dim Cell as TableCell
  dim Row as TableRow
  dim myBool as Boolean
  dim myimage as ImageButton
  
  dim ChildRows() as DataRow
  dim ChildTable as DataTable
  
  dim myRel as DataRelation
  dim bb() as integer
  
  dim CellStyle as new TableItemStyle
  cellStyle.borderwidth=unit.pixel(1)
  cellStyle.borderstyle=Borderstyle.solid
  cellStyle.wrap=false
  
  if myTable.ChildRelations.count=1 then '有從表
   myRel=myTable.ChildRelations(0)
   ChildTable =myRel.ChildTable
   m=ChildTable.Columns.count-1
   redim bb(m)
   myBool=True
   bb=SetCellSize(ChildTable)
  end if
  
  testTable=New Table
  testTable.borderwidth=unit.pixel(1)
  testTable.cellspacing=0
  testtable.cellPadding=0
  testTable.font.name="宋體"
  testTable.font.size=fontunit.point(fontsize)
  testTable.visible=true
  if signal<>"" then '遞歸調用時,字段名行形成的Table.id的賦值
   leng=len(signal)
   testTable.id="t" & mid(signal,2,leng-1) & "-0"
   testtable.visible=false
  else
   testTable.id="t" & "0" '初始時,字段名行形成的Table.id
   testTable.visible=true
  end if
  
  form1.controls.add(testtable)
  
  '********** 以下程序為生成表的字段名稱行的Table ********************
  
  Row=New tableRow
  Row.borderwidth=unit.pixel(1)
  m=rows.length
  
  if spaces>0 then
   for i=1 to spaces
   cell=new Tablecell
   cell.applyStyle(CellStyle)
   cell.width=unit.pixel(13)
   if not myBool then cell.rowspan=m+1
   row.cells.add(cell)
   next
  end if
  
  if myBool then
   cell=new Tablecell
   cell.applystyle(CellStyle)
   cell.backcolor=color.lightgray
   cell.bordercolor=color.black
   cell.width=unit.pixel(13) >   row.cells.add(cell)
  end if
  
  m=myTable.Columns.count-1
  
  for i=0 to m
   Cell=new tableCell
   dim str2 as string
   cell.applystyle(cellstyle)
   cell.backcolor=color.lightgray
   cell.bordercolor=color.black
   cell.text= myTable.columns(i).columnName
   cell.HorizontalAlign=HorizontalAlign.Center
   k=(fontsize+6)*aa(i)
   cell.width=unit.pixel(k)
   row.Cells.add(cell)
  next
  testtable.Rows.add(row)
  
  '************* 以下程序為生成表的各行紀錄的Tables *********************
  
  for i=0 to rows.length-1
   if myBool then
   testTable=New table
   testTable.borderwidth=unit.pixel(1)
   testTable.cellspacing=0
   testtable.cellPadding=0
   testTable.font.name="宋體"
   testTable.font.size=fontunit.point(fontsize)
   testTable.visible=true
   if signal<>"" then
   testTable.id="t" & mid(signal,2,leng-1) & "-" & (i+1).tostring
   testtable.visible=false
   else
   testTable.id="t" & (i+1).tostring
   testTable.visible=true
   end if
   form1.controls.add(testtable)
   end if
  
   myRow=rows(i)
  
   Row=New tableRow
   if myBool then
   if spaces>0 then
   for k=1 to spaces
   cell=new Tablecell
   cell.applystyle(cellstyle)
   cell.width=unit.pixel(13)
   row.cells.add(cell)
next
   end if
  
   Cell=New tableCell
   cell.width=unit.pixel(13)
   cell.applystyle(CellStyle) 

   myimage=New imagebutton
   myimage.imageurl="close.gif"
   if signal<>"" then
   myimage.id=signal & "-" & (i+1).tostring
   else
   myimage.id="e" & (i+1).tostring
   end if
   AddHandler myimage.Command, AddressOf ImageButton_Command
   myimage.imagealign=ImageAlign.absmiddle
   cell.controls.add(myimage)
   row.cells.add(cell)
   end if
  
   m=myTable.columns.count-1
  
   for j=0 to m
   cell=new tablecell
   cell.ApplyStyle(CellStyle)
   cell.text=myRow(myTable.columns(j)).tostring
   k=(fontsize+6)*aa(j)
   cell.width=unit.pixel(k)
   row.cells.add(cell)
   next
   testtable.rows.add(row)
  
  
   if myBool then '若有從表,遞歸調用
   dim spaces2 as integer
   spaces2=spaces+1
   ChildRows=myRow.GetChildRows(myRel)
   call ShowChildRows(ChildRows,bb,ChildTable,spaces2,myimage.id)
   end if
  next
  End Sub
  
  
  
  
  --------------------------------------------------------------------------------
  
  事件過程:
  在“Tables和ImageButtons的ID的命名規則”一節中給出了命名的規則,這裡舉例說明:
  如果點擊了id為e1的ImageButton,它所對應的網頁上的Table的id為t1,與t1相關的子表上的相應的記錄行在網頁上形成id為t1-1,t1-2,...t1-n的Tables,這裡 n為子表上的相應的記錄行數,而t1-0為子表的字段名行在網頁上形成的Table。如果e1的ImageUrl為“”close.gif,則將其設置為“”open.gif,並將t1-0,t1-1,...t1-n的Visible屬性設置為True。反之,除了要將e1的ImageUrl改為close.gif和將t1-0,t1-1,...t1-n的Visible屬性改為False外,如果t1-1,t1-2,...t1-n有對應id為e1-1,e1-2,...e1-n的ImageButton的,而這些ImageButtons中的某些ImageUrl為open.gif,即子表的子表的某些記錄行生成的Tables是打開的,則這些ImageUrl設置為close.gif。
  文章標題:Using Web Services Enhancements to Send SOAP Messages with Attachments
  程序如下:
   Sub ImageButton_Command(Sender as object,e as CommandEventArgs)
  dim myControl as Control
  dim str1 as string
  dim leng as integer
  
  str1=sender.id
  leng=len(str1)
  str1="t" & mid(str1,2,leng-1) & "-"
  
  if Sender.ImageUrl="close.gif" then
   Sender.ImageUrl="open.gif"
   for each myControl in form1.controls
   dim pos1 as integer=instr(leng+2,myControl.id,"-")
   if left(myControl.id,leng+1)=str1 and pos1=0 then myControl.visible=true
   next
  else
   Sender.ImageUrl="close.gif"
   for each myControl in form1.controls
   dim str0 as string=myControl.id
   if left(myControl.id,leng+1)=str1 then
   dim dTable as table
   dtable=ctype(myControl,table)
   if dtable.controls.count>0 then
   dim rowControl as control
   for each rowControl in dtable.controls
   dim drow as tablerow
   drow=ctype(rowControl,tablerow)
   if drow.controls.count>0 then
   dim cellControl as control
   for each cellControl in drow.controls
   dim dcell as tablecell
   dcell=ctype(cellControl,TableCell)
   if dcell.controls.count>0 then
   dim imageControl as control
   for each imageControl in dcell.controls
   dim dimage as imageButton
   dimage=ctype(imageControl,imageButton)
   dimage.ImageUrl="close.gif"
   next
   end if
   next
   end if
   next
   end if
 &nb sp; myControl.visible=false
   end if
   next
  end if
  End Sub
  
  
  
  
  --------------------------------------------------------------------------------
  
  應用實例:
  以羅斯文數據庫為例,該數據庫有客戶、訂單和訂單明細三個表文件,客戶和訂單兩張表在字段名“客戶ID”有一對多的關系,訂單和訂單明細在字段名“訂單ID”有一對多的關系。下述程序連接數據庫,形成DataSet後,調用子程序ShowTables。
   <%@Import Namespace=System.Data.oledb%>
  <%@Import Namespace=System.Data%>
  <%@Import Namespace=System.drawing%>
  <Html>
  <head><script language="VB" runat="server">
  sub Page_Load(Sender as Object, e as EventArgs)
  
  dim dsDataSet as DataSet=new DataSet()
  dim Constr,Conn as string
  
  dsdataSet=cache("mySet")
  if dsDataSet is Nothing
   Constr =server.mappath("northwind.mdb")
   Conn="provider=microsoft.jet.oledb.4.0; data source=" & Constr
   dsDataSet=new DataSet()
   dim odA as oledbDataAdapter=new oledbDataAdapter("select * from 客戶",Conn)
   odA.fill(dsDataSet,"Customers")
  
   odA.SelectCommand.CommandText="select * from 訂單"
   odA.fill(dsDataSet,"Orders")
  
   odA.SelectCommand.CommandText="select * from 訂單明細"
   odA.fill(dsDataSet,"Order_details")
  dsDataSet.Relations.Add("M",dsDataSet.Tables(0).Columns("客戶ID"),dsDataSet.Tables(1).Columns("客戶ID"))
  dsDataSet.Relations.Add("N",dsDataSet.Tables(1).Columns("訂單ID"),dsDataSet.Tables(2).Columns("訂單ID"))
  Cache("mySet")=dsdataSet
  end if
  call ShowTables(dsDataSet)
  end sub
  
   
  
  '子程序ShowTables添加處
  
  '子程序SetCellSize添加處
  
  '子程序ShowChildRows添加處
  
  '子程序ImageButton_Command添加處
  </script>
   
  </head>
  <body>
  <form id="form1" runat="server">
  </form>
  </body>
  </Html>
  
  將上述程序copy到記事本中,並將前面的程序copy到相應的子程序添加處,注意:在上述過程中可能會出現文本的斷行錯誤,在加以修改後,命名為.ASPx文件,運行結果如下圖:
  
  
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved