我用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的隐藏也会不正常。

解决方案 »

  1.   

    在点击的时候可以进行一个判断呀!! 如果当前状态为隐藏就显示,如果显示就隐藏,反正你想要什么结果就判断下呀!!  不行的话就去VIEWSTATE 中取这个值当前的状态,看行不?
      

  2.   

    我也搞在DetailsView,不会用,有没有它的些视频啊。
      

  3.   


    这种设置它为false的方法大多数时候是害你自己,大多数人对于失去状态的应用程序,而且是使用到你说的这种交互界面程序,毫无心理准备,所以遇害时无所适从。
      

  4.   

    你的“发现”我看不出什么原因。你写个简单的demo,演示一下!
      

  5.   

    DetailsView的确有那么一点点比较麻烦的啊!期待中…………
      

  6.   

    给你写了个demo。其实我并不喜欢隐藏GridView1,不过还是按照你的问题写了:<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestGridViewDetailsView.aspx.cs"
        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; }
        }
    }
      

  7.   

    其实我建议你把 Page_Prerender 中的那一行注释掉。隐藏GridView反而不太好看。
      

  8.   


    吴老师你好!
       问一下,页面第一次加载时,datadetail中是没有内容的,如果要默认它为girdview中的第一条,这个该如何实现呢?
      谢谢!
      

  9.   

    一个页面中有多个gridview 和datadetail的话,应该不会影响效率的吧? 主要是我的业务需要。暂时还没有好的解决方法。  这个gridview主要是用于显示,不需要操作。。
      

  10.   


    那么默认的,多写一条语句设置GridView的SelectIndex就可以了。通常因为需要丰富的theme机制,所以才需要强大的组件。当DetailsView1的Visible为false时,它是不会去绑定数据的。当页面回发的时候,你可以放一个Button然后测试GridView和DetailsView,它们也是不会去绑定数据的。可以将GridView和DetailsView放入两个独立的子程序ascx,只是在接口的属性和事件上协调它们。一旦调试通过,那么就可以在有足够时间的时候考虑加上OutputCache。当然客户端可以考虑使用Silverlight或者Flash来开发。
      

  11.   

    按照微软技术社区版主的指点,将SqlDataSource、dripdownlist等的EnableViewState设置="False",好像可以了。不知道是什么原因。