我用GridView1和DetailsView1,实现商品列表以及具体商品的编辑、删除功能,在点击GridView1中的具体商品后,GridView1.Visible = false,而DetailsView1.Visible = true,在更新后GridView1.Visible= true;DetailsView1.Visible = false;但我发现不能在DetailsView1_ItemUpdated事件里写DetailsView1.Visible = false;
否则 在实现了一次编辑更新后,再次点击GridView1某个具体商品就会出现 “未能加载视图状态。正在向其中加载视图状态的控件树必须与前一请求期间用于保存视图状态的控件树相匹配。例如,当以动态方式添加控件时,在回发期间添加的控件必须与在初始请求期间添加的控件的类型和位置相匹配。”其中 DetailsView1里面我用了模板列。是什么原因,应该怎么写?如果在page指令中加入EnableViewState="false" ,GridView1的隐藏也会不正常。
否则 在实现了一次编辑更新后,再次点击GridView1某个具体商品就会出现 “未能加载视图状态。正在向其中加载视图状态的控件树必须与前一请求期间用于保存视图状态的控件树相匹配。例如,当以动态方式添加控件时,在回发期间添加的控件必须与在初始请求期间添加的控件的类型和位置相匹配。”其中 DetailsView1里面我用了模板列。是什么原因,应该怎么写?如果在page指令中加入EnableViewState="false" ,GridView1的隐藏也会不正常。
这种设置它为false的方法大多数时候是害你自己,大多数人对于失去状态的应用程序,而且是使用到你说的这种交互界面程序,毫无心理准备,所以遇害时无所适从。
Inherits="TestGridViewDetailsView" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>演示GridView+DetailsView</title>
</head>
<body>
<form id="form1" runat="server">
<table style="width:100%">
<tr>
<td>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" AutoGenerateSelectButton="True"
BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px"
CellPadding="4" DataKeyNames="Name" DataSourceID="ObjectDataSource1" ForeColor="Black"
GridLines="Vertical"
onselectedindexchanged="GridView1_SelectedIndexChanged" >
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:BoundField DataField="Name" HeaderText="名称" />
<asp:BoundField DataField="Price" HeaderText="售价" DataFormatString="{0:c}" HtmlEncode="False" />
</Columns>
<FooterStyle BackColor="#CCCC99" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
<RowStyle BackColor="#F7F7DE" />
<SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#FBFBF2" />
<SortedAscendingHeaderStyle BackColor="#848384" />
<SortedDescendingCellStyle BackColor="#EAEAD3" />
<SortedDescendingHeaderStyle BackColor="#575357" />
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetProducts"
TypeName="BLL"></asp:ObjectDataSource>
</td>
<td>
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" DataSourceID="ObjectDataSource2"
Height="50px" Width="125px" AutoGenerateEditButton="True" Visible="false"
onitemupdated="DetailsView1_ItemUpdated"
onmodechanged="DetailsView1_ModeChanged">
<Fields>
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Price" HeaderText="Price" SortExpression="Price" />
<asp:TemplateField HeaderText="最后更新时间" SortExpression="最后更新时间">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("最后更新时间") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
<asp:ObjectDataSource ID="ObjectDataSource2" runat="server" SelectMethod="GetProductByName"
TypeName="BLL" UpdateMethod="UpdateProductByName" OnUpdating="ObjectDataSource2_Updating">
<SelectParameters>
<asp:ControlParameter ControlID="GridView1" Name="name" PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="name" Type="String" />
<asp:Parameter Name="price" Type="Decimal" />
<asp:Parameter Name="updateTime" Type="DateTime" />
</UpdateParameters>
</asp:ObjectDataSource>
</td>
</tr>
</table>
<br />
</form>
</body>
</html>
using System;
using System.Web.UI.WebControls;public partial class TestGridViewDetailsView : System.Web.UI.Page
{
protected void ObjectDataSource2_Updating(object sender, ObjectDataSourceMethodEventArgs e)
{
e.InputParameters["updateTime"] = DateTime.Now;
} protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
this.DetailsView1.Visible = true;
this.DetailsView1.ChangeMode(DetailsViewMode.Edit);
} protected void DetailsView1_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
{
this.GridView1.DataBind();
} protected void DetailsView1_ModeChanged(object sender, EventArgs e)
{
this.DetailsView1.Visible = this.DetailsView1.CurrentMode == DetailsViewMode.Edit;
} protected void Page_Prerender(object sender, EventArgs e)
{
this.GridView1.Visible = !this.DetailsView1.Visible;
}
}最后是提供领域数据的BLL层代码:using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;public static class BLL
{
private static List<Product> _Products; public static List<Product> GetProducts()
{
if (_Products == null)
{
_Products = new List<Product>(){
new Product { Name="月亮美眉", Price=9009999},
new Product{ Name="屋子", Price=83722323},
new Product{ Name="一本书", Price=20}
};
}
return _Products;
} public static Product GetProductByName(string name)
{
return GetProducts().FirstOrDefault(p => p.Name == name);
} public static void UpdateProductByName(string name, decimal price, DateTime updateTime)
{
var obj = GetProductByName(name);
obj.Price = price;
obj.最后更新时间 = updateTime;
}
}public class Product
{
public string Name { get; set; }
public decimal Price { get; set; } private DateTime _最后更新时间 = DateTime.Now; public DateTime 最后更新时间
{
get { return _最后更新时间; }
set { _最后更新时间 = value; }
}
}
吴老师你好!
问一下,页面第一次加载时,datadetail中是没有内容的,如果要默认它为girdview中的第一条,这个该如何实现呢?
谢谢!
那么默认的,多写一条语句设置GridView的SelectIndex就可以了。通常因为需要丰富的theme机制,所以才需要强大的组件。当DetailsView1的Visible为false时,它是不会去绑定数据的。当页面回发的时候,你可以放一个Button然后测试GridView和DetailsView,它们也是不会去绑定数据的。可以将GridView和DetailsView放入两个独立的子程序ascx,只是在接口的属性和事件上协调它们。一旦调试通过,那么就可以在有足够时间的时候考虑加上OutputCache。当然客户端可以考虑使用Silverlight或者Flash来开发。