Các điều khiển dữ liệu ASP.Net

Một phần của tài liệu Giáo trình Thiết kế web (Nghề Quản trị mạng máy tính Cao đẳng) (Trang 77 - 111)

3. Các đối tượng ADO.Net:

3.3. Các điều khiển dữ liệu ASP.Net

3.3.1. Giới thiệu các điều khiển dữ liệu

ASP.NET 2.0 cung cấp một vài kiểu điều khiển Data Source Controls làm việc tương thích với các kiểu Data Sources khác nhau, chúng bao gồm:

+ Điều khiển SqlDataSource control cho phép connections đến hầu hết các CSDL quan hệ.Providermặc định là cho CSDL SQL Server, ngoài ra còn cho Oracle, OLEDB,.v.v…

+ Điều khiển AccessDataSource control là trường hợp đặc biệt của điều khiển SqlDataSource control chứa provider được tối ưu cho CSDL Microsoft Access.

+ Điều khiển XMLDataSource control cho phép connection tới XML sources. + Điều khiển SiteMapDataSource control là mẫu được thiết kế riêng cho điều khiển XMLDataSource control.

+ Điều khiển ObjectDataSource control connects tới các đối tượng business.

* Giới thiệu Data-Bound Controls

Data-bound controls là các điều khiển buộc dữ liệu, cung cấp kết nối giữa các điều khiển data source controls với người sử dụng. Chúng có thể được phân loại theo cách hiển thị như sau:

+ Tabular Controls: Là các điều khiển hiển thị một danh sách dữ liệu của các

bản ghi, gồm các điều khiển GridView, DataList, Repeater .v.v…

+ Single Record Display Controls: Như các điều khiển DetailsView, và

FormView hiển thị từng bản ghi ở tại mỗi thời điểm.

+ Selection List Controls: Là điều khiển cho phép người sử dụng lựa chọn. Có 2 điều khiển hiển thị một trường dữ liệu đó là ListBox controls và DropDownList controls.

+ Tree Controls: Là các điều khiển dữ liệu lưu trữ trên các nút.

3.3.2. Data Binding Expression

ASP.NET buộc dữ liệu thông thường qua các khai báo hoặc qua các biểu thức buộc dữ liệu inline. Các biểu thức buộc dữ liệu (Data Binding Expressions) được khai báo trong cặp <%# ... %>

Các phương thức Eval() và Bind() được sử dụng để buộc các biểu thức với các điều khiển. Các biểu thức buộc dữ liệu được giải quyết khi phương thức DataBind() của các điều khiển được gọi trong file Code Behind. Thường thì phương thức này được gọi trong sự kiện Page_Load. Các điều khiển ASP.NET nhe GridView, DetailView, FormView, … gọi phương thức DataBind() để thực thi kết nối khi chúng được buộc vào một điều khiển Data Sourcce.

Biểu thức Mô tả

<%# Eval("PropertyName") %> Dùng định nghĩa cách liên kết dữ liệu chỉ đọc. Ví dụ: xuất dữ liệu ra Label.

<%# Bind("PropertyName") %> Dùng định nghĩa cách liên kết dữ liệu đọc ghi (cập nhật dữ liệu). Ví dụ: xuất dữ liệu ra TextBox, …

Ví dụ:

<asp:FormView ID="FormView1"runat="server"AllowPaging="True"

DataKeyNames="CustomerID"

DataSourceID="SqlDataSource1"> <EditItemTemplate>

CustomerName:

<asp:TextBoxID="txtCustName"runat="server"Text='<%# Bind("CName") %>'>

</asp:TextBox> </EditItemTemplate> <ItemTemplate> CustID:

<asp:Label ID="lblCustID"runat="server"Text='<%# Eval("CID") %>'>

</asp:Label> </ItemTemplate> </asp:FormView>

3.3.3. Giới thiệu điều khiển Data Bound

Data-bound controls là các điều khiển buộc dữ liệu, cung cấp kết nối giữa các điều khiển data source controls với người sử dụng.

Điều khiển GridView:

Điều khiển Grid View là điều khiển phát triển từ điều khiển Data Grid (ASP.NET 1.0). Giống như DataGrid, GridView được sử dụng để hiển thị dữ liệu như một bảng dữ liệu. Sử dụng GridView để hiển thị, edit, delete, sort, và phân trang.

GridView và DataGrid có thể buộc vào một điều khiển DataSourceControl, nhưng DataGrid chỉ cho chọn dữ liệu. Việc Sort, paging, updates, và delete phải được code bằng tay. GridView hỗ t rợ thuộc tính DataSourceID làm cho điều khiển có thể tích hợp được các khả năng sorting, paging, updating, và deleting của điều khiển data source.

Ví dụ 3.4. Sử dụng GridView để hiển thị dữ liệu, sorting và paging (vidu3_5.aspx)

<%@PageLanguage="VB"%> <scriptrunat="server"></script> <body>

<formid="form1"runat="server">

<asp:SqlDataSourceID="SqlDataSource1"runat="server"

ConnectionString="<%$ ConnectionStrings:MyConn %>"

SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]"> </asp:SqlDataSource>

<asp:GridViewID="MyGridView"runat="server"AllowPaging="True"

AllowSorting="True"AutoGenerateColumns="False"PageSize="2"

DataSourceID="SqlDataSource1"DataKeyNames="ProductID"> <Columns>

<asp:BoundFieldDataField="ProductID"HeaderText="ProductID"

SortExpression="ProductID"/>

<asp:BoundFieldDataField="ProductType"HeaderText="ProductType"/> <asp:BoundFieldDataField="ProductName"HeaderText="ProductName" /> <asp:BoundFieldDataField="ProductDescription"

HeaderText="ProductDescription" />

<asp:BoundFieldDataField="ProductSize"HeaderText="ProductSize" /> <asp:BoundFieldDataField="UnitPrice"HeaderText="UnitPrice" /> <asp:TemplateFieldHeaderText="Image">

<ItemTemplate>

Eval("ProductImageURL")%>'/> </ItemTemplate>

</asp:TemplateField> </Columns>

<PagerSettingsFirstPageText="First"LastPageText="Last"

PageButtonCount="4"Position="TopAndBottom"

FirstPageImageUrl="~/Images/btnFirst.gif"

LastPageImageUrl="~/Images/btnLast.gif"

NextPageImageUrl="~/Images/btn_next.gif"NextPageText="Next"

PreviousPageImageUrl="~/Images/btn_previous.gif"

PreviousPageText="Previous" /> </asp:GridView>

</form> </body>

Ta thực hiện thiết kế trong tab Design của cửa sổ Web Page Designer:

- Kéo điều khiển GridView vào cửa sổ thiết kế. Sau đó mở Smart Task và chọn: DataSource, Paging để phân trang và Sorting dùng để sắp xếp dữ liệu (Hình 3.8).

- Chọn Add New Column để thêm một cột thể hiện hình ảnh các sản phẩm. Xuất hiện hình 3.9. Chọn kiểu trường là TemplateFile và Header Text là Image. Sau đó click OK.

- Chọn Edit Template và chọn Template vừa tạo để hiệu chỉnh xuất hiện cửa sổ hình 3.10. Trong cửa sổ này ta thêm thẻ <Image> và buộc điều khiển này vào trường ProductImageURL

- Thực hiện phân trang hiển thị. Trong cửa sổ Properties mở rộng thuộc tính PagerSetting và Page size để định dạng phân trang (hình 3.11):

+ Mode: Kiểu duyệt trang (NextPreviousFirstLast, Numeric, NextPrevious, NumericFirstLast).

+ NextPageImagerURL: Địa chỉ ảnh của nút Next. + NextPageText: Chuỗi Text của nút Next

Tương tự cho các nút còn lại,… + Pagesize: Số bản ghi trên một trang Kết quả duyệt ví dụ 3.4 trong hình 3.12.

Hình 3.9.Cửa sổ Add File

Hình 3.11.Cửa sổ Properties

Hình 3.12.Duyệt ví dụ 3.4.

Là các điều khiển mà toàn bộ thông tin của bản ghi sẽ được hiển thị trên một cell. Điểm khác nhau giữa hai điều khiển này là DataList có định dạng và template mặc định còn Repeater không có mà phải tự thiết kế. Cách tạo DataList tương tự như GridView.

Ví dụ 3.5.Sử dụng điều khiển DataList (vidu3_6.aspx) <%@PageLanguage="VB"%>

<scriptrunat="server"> </script>

<body>

<formid="form1"runat="server">

<asp:SqlDataSourceID="SqlDataSource1"runat="server"ConnectionString="<%$ ConnectionStrings:MyConn %>" SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]">

</asp:SqlDataSource>

<asp:DataListID="DataList1" runat="server"DataSourceID="SqlDataSource1"

RepeatColumns="2"> <ItemTemplate>

<asp:ImageID="Image1"runat="server"

ImageUrl='<%# Eval("ProductImageURL") %>' /><br/> Mãsản phẩm:

<asp:LabelID="ProductIDLabel"runat="server"

Text='<%# Eval("ProductID") %>'></asp:Label><br/> Tênsản phẩm:

<asp:LabelID="ProductNameLabel"runat="server"Text='<%# Eval("ProductName") %>'></asp:Label><br/>

Kiểusản phầm:

<asp:LabelID="ProductTypeLabel"runat="server"

Text='<%# Eval("ProductType")%>'></asp:Label><br/> Mô tả:

<asp:LabelID="ProductDescriptionLabel"runat="server"Text='<%# Eval("ProductDescription") %>'></asp:Label>

Kích thước sản phẩm:

<asp:LabelID="ProductSizeLabel"runat="server"

Text='<%# Eval("ProductSize")%>'></asp:Label><br/> Giásản phẩm (USD):

<asp:LabelID="UnitPriceLabel"runat="server"

Text='<%# Eval("UnitPrice") %>'></asp:Label><br/> </ItemTemplate>

</asp:DataList> </form>

</body>

Hình 3.13.Duyệt ví dụ 3.5.

Ví dụ 3.6.Sử dụng điều khiển Repeater (vidu3_7.aspx) <%@PageLanguage="VB"%>

<formid="form1"runat="server">

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:MyConn %>"

SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]"> </asp:SqlDataSource>

<asp:RepeaterID="Repeater1" runat="server"DataSourceID="SqlDataSource1"> <ItemTemplate>

<asp:ImageID="Image1"runat="server"

ImageUrl='<%# Eval("ProductImageURL") %>' /><br/> Mãsản phẩm:

<asp:LabelID="ProductIDLabel"runat="server"

Text='<%# Eval("ProductID") %>'></asp:Label><br/> Tênsản phẩm:

<asp:LabelID="ProductNameLabel"runat="server"Text='<%# Eval("ProductName") %>'></asp:Label><br/>

Kiểusản phầm:

<asp:LabelID="ProductTypeLabel"runat="server"

Text='<%# Eval("ProductType")%>'></asp:Label><br/> Mô tả:

<asp:Label ID="ProductDescriptionLabel"runat="server"Text='<%# Eval("ProductDescription") %>'></asp:Label>

Kích thước sản phẩm:

<asp:LabelID="ProductSizeLabel"runat="server"

Text='<%# Eval("ProductSize")%>'></asp:Label><br/> Giásản phẩm (USD):

<asp:LabelID="UnitPriceLabel"runat="server"

Text='<%# Eval("UnitPrice") %>'></asp:Label><br/> </ItemTemplate>

</asp:Repeater> </form>

Kết quả triệu gọi ví dụ 3.6. cho trong hình 3.14.

Hình 3.14.Duyệt ví dụ 3.6.

Điều khiển DetailsView và FormView Controls:

Đây là hai điều khiển buộc dữ liệu, tại một thời điểm chỉ hiển thị một bản ghi. Khi buộc dữ liệu, điều khiển DetailsView tự động tạo các template, FormView chỉ tạo ra thẻ trắng và người thiết kế phải tự thiết kế các template.

Ví dụ 3.8. Minh họa việc sử dụng kết hợp điều khiển GridView và điều khiển DetailView. Điều khiển GridView hiển thị danh sách các sản phẩm còn điều khiển DetailView hiển thị thông tin chi tiết sản phẩm mà người dùng chọn trên điều khiển GridView.

<%@PageLanguage="VB"%> <formid="form1"runat="server">

<asp:SqlDataSourceID="SqlDataSource1"runat="server"

ConnectionString="<%$ ConnectionStrings:MyConn %>"

SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [UnitPrice] FROM [Products]">

</asp:SqlDataSource>

<asp:GridView ID="GridView1" runat="server"AutoGenerateColumns="False"

DataSourceID="SqlDataSource1"AllowPaging="True"BackColor="White"

BorderColor="#E7E7FF"BorderStyle="None"BorderWidth="1px"

CellPadding="3"DataKeyNames="ProductID" PageSize="5"

GridLines="Horizontal"> <Columns>

<asp:CommandFieldShowSelectButton="True"ButtonType="Image"

SelectImageUrl="~/Images/dn.gif" />

SortExpression="ProductID" /> <asp:BoundFieldDataField="ProductType"

HeaderText="Kiểusản phẩm"SortExpression="ProductType"/> <asp:BoundFieldDataField="ProductName"

HeaderText="Tênsản phẩm"SortExpression="ProductName"/> <asp:BoundFieldDataField="UnitPrice"

HeaderText="Gi&#225;(USD)"SortExpression="UnitPrice" /> </Columns>

<PagerSettingsPageButtonCount="4" />

<FooterStyleBackColor="#B5C7DE"ForeColor="#4A3C8C" /> <RowStyleBackColor="#E7E7FF"ForeColor="#4A3C8C" />

<SelectedRowStyle BackColor="#738A9C" Font-

Bold="True"ForeColor="#F7F7F7"/>

<PagerStyleBackColor="#E7E7FF"ForeColor="#4A3C8C"

HorizontalAlign="Right"/>

<HeaderStyleBackColor="#4A3C8C"Font-Bold="True"ForeColor="#F7F7F7" /> <AlternatingRowStyleBackColor="#F7F7F7"/>

</asp:GridView>

<asp:SqlDataSourceID="SqlDataSource2"runat="server"ConnectionString="<%$ ConnectionStrings:MyConn %>" SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize],

[ProductImageURL], [UnitPrice] FROM [Products] WHERE ([ProductID] = @ProductID)">

<SelectParameters>

<asp:ControlParameterControlID="GridView1"DefaultValue="2"

Name="ProductID"PropertyName="SelectedValue"Type="Int32" /> </SelectParameters>

</asp:SqlDataSource> Thông tin chi tiết<br/>

<asp:DetailsViewID="DetailsView1"runat="server"AutoGenerateRows="False"

BackColor="White"BorderColor="#E7E7FF"BorderStyle="None"

BorderWidth="1px"CellPadding="3"DataSourceID="SqlDataSource2"

GridLines="Horizontal"Height="50px"Width="440px"> <PagerSettingsPageButtonCount="4" />

<FooterStyleBackColor="#B5C7DE" ForeColor="#4A3C8C" />

<EditRowStyleBackColor="#738A9C"Font-Bold="True"ForeColor="#F7F7F7" /> <RowStyleBackColor="#E7E7FF"ForeColor="#4A3C8C" />

<PagerStyleBackColor="#E7E7FF"ForeColor="#4A3C8C"

HorizontalAlign="Right"/> <Fields>

<asp:TemplateFieldHeaderText="Ảnh"> <ItemTemplate>

<asp:Image ID="Image1"runat="server"ImageUrl='<%# Eval("ProductImageURL") %>' />

</ItemTemplate> </asp:TemplateField>

<asp:BoundFieldDataField="ProductName"HeaderText="T&#234;nsản phẩm"SortExpression="ProductName" />

<asp:BoundFieldDataField="ProductID"HeaderText="Mãsản phẩm"

SortExpression="ProductID" />

<asp:BoundFieldDataField="ProductType"HeaderText="Kiểusản phẩm"

SortExpression="ProductType" />

<asp:BoundFieldDataField="ProductDescription"HeaderText="Mô tả:"/> <asp:BoundFieldDataField="ProductSize"HeaderText="Kích thước"

SortExpression="ProductSize" />

<asp:BoundFieldDataField="UnitPrice"HeaderText="Đơn giá:" /> </Fields>

<HeaderStyleBackColor="#4A3C8C"Font-Bold="True"ForeColor="#F7F7F7" /> <AlternatingRowStyleBackColor="#F7F7F7" />

</asp:DetailsView> </form>

Chú ý: Xây dựng mệnh đề Where cho điều khiển SqlDataSource2 để kết nối dữ liệu giữa hai điều khiển như hình 3.14.

Kết quả duyệt ví dụ 3.8. cho trong hình 3.15.

Hình 3.15.Duyệt ví dụ3.8.

3.3.4. Giới thiệu điều khiển Data Sources

Điều khiển SqlDataSource control: Ta sử dụng điều khiển SqlDataSource controltheo các bước cơ bản sau:

- Trong cửa sổ thiết kế trang Design View, kéo điều khiển

SqlDataSource controlvào vùng thiết kế (hình 3.16).

Hình 3.16.Cửa sổ thiết kế Web Page Designer

- Mở smart task panel và click Configure Data Source. Xuất hiện cửa sổ Choose your Data connection hình 3.10. Chọn New Connection.

Hình 3.17.Cửa sổ Choose your Data connection

- Trong cửa sổ Cửa sổ Add connection (hình 3.17) ta nhập các thông tin kết nối và click OK để quay về cửa sổ 3.16 và chọn Next để tiếp tục.

Hình 3.18 Cửa sổ Addconnection

- Trong cửa sổ Save connection string to the Application Configuration file (hình 3.19). Cho phép có lựa chọn save chuỗi kết nối này trong file web config hay không?

Hình 3.19.Cửa sổ Save connection string

- Trong cửa sổ Configure the Select Statement (hình 3.20) ta chọn các trường cho câu lệnh Select. Chú ý, trong cửa sổ này có các nút Where để thiết lập cho mệnh đề Where cho câu lệnh Select (hình 3.21); nút Order By để sắp xếp dữ liệu.

Hình 3.20.Cửa sổ Configure the SelectStatement

- Chọn Next, xuất hiện cửa sổ Test Query (hình 3.22) để Test truy vấn vừa tạo.

Hình 3.21.Cửa sổ thiết lập cho mệnh đềWhere. - Chọn Finsh để kết thúc.

Hình 3.22.Cửa sổ TestQuery. Các bước trên tương ứng với khai báo thẻ như sau: <asp:SqlDataSourceID=”SqlDataSource1” runat=”server”

ConnectionString=”<%$ ConnectionStrings:MyConn %>”

SelectCommand=”SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]”>

</asp:SqlDataSource>

Chuỗi kết nối được khai báo trong tệp web config như sau: <connectionStrings>

<addname=”MyConn”connectionString=”Data Source=.;Initial Catalog=QLBanHang;User ID=sa;Password=12102006”

providerName=”System.Data.SqlClient”/> </connectionStrings>

Chú ý:

- Khi không Save chuỗi kết nối trong tệp web config thì chuỗi kết nối đó sẽ được khai báo tường minh trong source như sau.

- Trong lập trình người ta thường kết hợp hai cách thiết kế: Dùng chỉ dẫn của Design View sau đó chuyển sang Source để hiệu chỉnh lại.

<asp:SqlDataSourceID="SqlDataSource1"runat="server"

ConnectionString="Data Source=.;Initial Catalog=QLBanHang;User ID=sa;Password=12102006"ProviderName="System.Data.SqlClient"

SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]">

</asp:SqlDataSource>

3.3.5. Các thao tác dữ liệu với Data Controls

a) Giới thiệu các thao tác ghi dữ liệu

Không phải tất cả các điều khiển dữ liệu đều hỗ trợ cho việc ghi dữ liệu. Đối với các điều khiển data source controls, tất cả đều support cho việc ghi dữ liệu trừ điều khiển SiteMapDataSource.

Nhưng giữa các điều khiển buộc dữ liệu (data-binding controls) còn có khá nhiều các hạn chế. Các điều khiển chọn danh sách dữ liệu (DropDownList và ListBox) không support cho việc ghi dữ liệu. Các điều khiển buộc dữ liệu trong phiên bản mới ASP.NET 2.0 support cung cấp các phương thức tốt nhất cho việc ghi dữ liệu là: GridView, DetailsView, và FormView.

Tuy nhiên, GridView chỉ có thể update các bản ghi đã tồn tại, không tạo mới bản ghi đã tồn tại, không tạo mới các bản ghi. DataList và Repeater có thể sử dụng cho việc ghi dữ liệu, nhưng chúng là các điều khiển trong các phiên bản cũ nên trong một số trường chúng ta phải sử dụng các công nghệ cũ trong ASP.NET 1.1.

b) Updating các bản ghi

Trước khi đi vào các thao tác ghi dữ liệu ta xét thuộc tính DataKeyNames của điều khiển buộc dữ liệu liên quan đến các thao tác đó.

Thuộc tính DataKeyNames:

Tại cùng một thời điểm ta có thể có cùng một vài kiểu ghi dữ liệu cho một trường, do đó Visual Web Developer thêm thuộc tính DataKeyNamescho điều khiển buộc dữ liệu với mục đích giữ cả hai giá trị cũ và mới của một trường nào đó làm cho việc ghi dữ liệu được thực hiện một cách chính xác.

Để hiểu vai trò của thuộc tính DataKeyNames, ta hình dung trong hệ thống web site có một bảng ghi thông tin các ý kiến phản hổi từ khách hàng gọi là Comments. Trong bảng ta có một trường đầu tiên là trường kiểu số CommentsID nhận giá trị duy nhất cho mỗi dòng. Khách hàng sẽ gửi các ý kiến kiến phản hồi của mình và được lưu trong bảng. Đến một lúc nào đó các thông tin được sắp xếp lộn xộn và nhà quản trị phải thay đổi các ID cho các ý kiến đó, ví dụ từ 20 chuyển sang 19. Để làm điều này, người quản trị sẽ chọn bản ghi muốn thay đổi (chẳng hạn dùng điều khiển Grid view) và ASP.NET 2.0 sẽ lưu giá trị ID đó vào một tham số. Người quản trị sẽ gửi câu lệnh như sau đến database:

UPDATECommentsSETComment =19WHEREComment =@CommentID

Lưu ý là trong câu lệnh trên tên trường đã thay đổi (CommentsID) để câu lệnh nhận dạng bản ghi cần thay đổi giá trị. Đúng ra phải là WHERE CommentsID=@CommentsID nhưng sẽ bị xảy ra xung đột bởi vì @CommentsID nhận hai giá trị: Một giá trị cũ được lưu trên GridView (giá trị 20) và một giá trị mới do người quản trị nhập vào (19).

DataKeyNames giải quyết vấn đề này bằng cách tạo một từ điển giữ hai giá trị này cho các trường trong danh sách của chúng: Một giá trị cũ và một giá trị mới. Khi câu lệnh được gửi đến Database, ASP.NET sử dụng khả năng thông minh của mình để cung cấp giá trị mới từ DataKeyNames cho mệnh đề SET của câu lệnh và sử dụng giá trị cũ từ DataKeyNames cho mệnh của câu lệnh.

Thật là lãng phí và chậm khi load up từ điển DataKeyNames với mọi trường, đặc biệt là bởi vì hầu hết các trường không gây ra sự xung đột như trên. Visual Web Developer tự động adds các trường mà cấu trúc của nó duy nhất trong database.

Ta sử dụng thuộc tính DataKeyNames để thiết lập một danh sách các trường (cách nhau bởi dấu phẩy) thể hiện khóa chính của data source. Khi thuộc tính

DataKeyNames được thiết lập thì các điều khiển buộc dữ liệu (DetailsView, FormView, GridView) tự động tạo đối tượng DataKey thể hiện trường hoặc các trường khóa của bản ghi hiện tại và lưu trữ trong thuộc tính DataKey của nó. Khi thuộc tính AutoGenerateColumns của các đối tượng buộc dữ liệu thiết lập là True thì các trường chỉ định trong DataKeyNames tự động thiết lập là Read Only.

Một phần của tài liệu Giáo trình Thiết kế web (Nghề Quản trị mạng máy tính Cao đẳng) (Trang 77 - 111)

Tải bản đầy đủ (PDF)

(111 trang)