请教Asp:ObjectDataSource 中传值问题 ControlParameter 以及工作流程!~~~~~~~~~~~~~~~~~~~~~

LT_Friends 2010-04-29 04:03:51

<asp:ObjectDataSource ID="ods1" runat="server" TypeName="Namespace.method1BO"
SelectMethod="GetXXXs">
</asp:ObjectDataSource>

<asp:GridView ID="gv1" runat="server"
DataSourceID="ods1" DataKeyNames="DId" AutoGenerateColumns="false">
<Columns>
<asp:CommandField ButtonType="Link" ShowSelectButton="true" />
<asp:BoundField HeaderText="ID" DataField="DId" />
</Columns>
</asp:GridView>


第一个GridView添加ods1数据源,调用GetXXXs()无参方法,然后显示数据信息,其中手动添加2个列:Select和Id列


<asp:ObjectDataSource ID="ods2" runat="server" TypeName="Namespace.method2BO"
SelectMethod="GetXByDId">
<SelectParameters>
<asp:ControlParameter ControlID="gv1" PropertyName="SelectedValue"
Type="Int64" Name="DId" />
</SelectParameters>
</asp:ObjectDataSource>

<asp:GridView ID="gv2" runat="server"
DataSourceID="osd2" DataKeyNames="VId" >
</asp:GridView>


第二个GridView(gv2)要响应前一个GridView(gv1)的select事件,每次在gv1点击select事件,它会把DId值传给第二个数据源,然后调用第二个数据源的GetXByDId方法,再返回一组信息显示到gv2上。

代码没有问题,都正确运行,显示也正确.每次点击gv1每行的select,都会在gv2正确显示相应的信息.

我的问题是:

1.当点击gv1的select linkButton时,它是怎么把DId值传给osd2的?是调用gv1.SelectedValue 取的值吗?但是我设过断点调试过,gv1.SelectedValue不是正确的值。(是在Page_Load设置断点的)

2.上述的过程是完全在.aspx页面写的,就是后台的cs代码里一点都没有,所以无法去调试。比如说点击select时,它到底是不是一个事件?

3.这个程序我写的话,会是把gv1的select做个事件,然后响应事件,再赋值给osd2,然后再绑定到gv2中。现在gv2是怎么监听select点击的?
...全文
486 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
T_long 2010-05-17
  • 打赏
  • 举报
回复
收藏该贴
vrhero 2010-04-30
  • 打赏
  • 举报
回复
楼主比这个版区多数不求甚解的人强多了...我就再给你解释一下...

这几个问题涉及到的知识是很多的,除了我上面提到的那些基础知识,ObjectDataSource和GridView能够实现“联动”的主要知识点有两个...数据源控件和数据绑定控件...

实现了IDataSource接口的所有类都是数据源控件,但通常ASP.NET数据源控件由DataSourceControl抽象类派生...
[Quote=引用 MSDN:]
IDataSource 接口作为所有 ASP.NET 数据源控件的基础,使用两个方法定义了一个基本的数据绑定结构概念,这两个方法分别是 GetView 和 GetViewNames。这个概念就是,所有数据源控件都支持其数据的一个或多个命名视图。数据源视图对象类似于 System.Data 命名空间中的 DataView 抽象,它是一种数据可绑定的自定义的数据视图,用于排序、筛选和该视图定义的其他数据操作。数据源控件的核心是检索数据视图。

数据源控件可以有一个或多个关联的数据源视图对象。一些数据源控件(包括表示关系数据库的数据源控件,如 SqlDataSource 和 AccessDataSource)仅支持一个视图。另一些数据源控件(包括分层数据源控件,如 SiteMapDataSource)支持多个视图。数据源视图定义数据源的功能及其支持的操作。

总之,数据源控件实现 IDataSource 接口,支持这些控件表示的数据的一个或多个命名视图,并始终支持从这些控件表示的数据源中检索数据。数据源控件总是根据需要检索数据,如在数据绑定控件上调用 DataBind 时。[/Quote]
而从DataBoundControl类派生的所有类都是数据绑定控件,都可以绑定到数据源控件...
[Quote=引用 MSDN:]
当 DataBoundControl 绑定到数据源控件时,会在运行时自动执行数据绑定。也可以将数据源控件与符合以下条件的 ASP.NET 控件一起使用:公开 DataSource 或 DataSourceID 属性并支持基本数据绑定但不从 DataBoundControl 派生。在使用这些数据绑定控件时,必须显式调用 DataBind 方法。[/Quote]
当你为GridView的DataSourceID属性指定了有效值时,ASP.NET在编译页面时将自动为绑定的数据源控件和数据绑定控件生成内建的绑定代码,包括为相应的Web服务器控件事件生成委托和订阅,并在执行加载页面时自动调用GetData和PerformDataBinding方法,读取你指定的DataKeyNames属性、SelectMethod属性、SelectParameters节点等信息通过反射获取相应的Select方法及其参数执行查询,从而完成数据绑定...

这个过程“拖控件”是非常容易的但其背后的原理机制是非常复杂的,有兴趣的话多看看MSDN逐步去了解,但不要心急更不要学那些浮躁的人不求甚解...
LT_Friends 2010-04-30
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 sandy945 的回复:]
你可以查看页面生成的源文件

会发现 html form tag 的指向是 .aspx 页本身, “gv1中的select点击时” 会执行页面上 存在的js脚本

效果是让 runat="server" 的 form 提交,提交前它会设置几个参数, 用于告诉Page 是谁触发了回发

然后Page 会重新创建相关控件 并还原数据 之后 根据参数 找到了你选中的行

而 Object……
[/Quote]

OK,谢谢,我想该结贴了,谢谢大家!
阿非 2010-04-30
  • 打赏
  • 举报
回复
你可以查看页面生成的源文件

会发现 html form tag 的指向是 .aspx 页本身, “gv1中的select点击时” 会执行页面上 存在的js脚本

效果是让 runat="server" 的 form 提交,提交前它会设置几个参数, 用于告诉Page 是谁触发了回发

然后Page 会重新创建相关控件 并还原数据 之后 根据参数 找到了你选中的行

而 ObjectDataSource 的工作机制 应该是每次 页面呈现前都会执行 select 方法

第一次 gv2 没有内容 是因为 gv1 没有选择项,并不是 osd2 没有执行 select 方法

---------------------------------------------------------------------------

当你的 gv1 有选择项 ,同时触发了页面回发(页面提交)的时候

osd2 执行 select 方法 , 将获取到的数据 绑定给 gv2

LT_Friends 2010-04-30
  • 打赏
  • 举报
回复
再次感谢大家!
其实我最想知道的是第三个问题,就是说gv2,也就是osd2,它是怎么监听select点击的?

通过大家的解释,我想是这样的:

1。当gv1中的select点击时,浏览器把form元素中的值post到服务器,我前面设置的DataKeyNames="DId",服务器postback一些信息,我就可以取到gv1.SelectedValue的值.

2.然后ObjectDataSource控件每次刷新页面时都会重新计算一次数据。现在osd2里设置了监听gv1.SelectedValue,取到相应的值去数据库查询,然后自动绑定。


是这样吗?
koukoujiayi 2010-04-30
  • 打赏
  • 举报
回复
正在加班,再说两句:
事实上可以将前台ods2绑定的gv1的Did参数,用后台来设置,例如将原来的
<SelectParameters>
<asp:ControlParameter ControlID="gv1" PropertyName="SelectedValue" Type="Int64" Name="DId" />
</SelectParameters>
改成:
<SelectParameters>
<asp:Parameter Name="DId" Type="Int64" />
</SelectParameters>

再在后台gv1的SelectedIndexChanged事件下,设置ods2的参数,代码如下:
protected void gv1_SelectedIndexChanged(object sender, EventArgs e)
{
ods2.SelectParameters["Did"].DefaultValue = gv1.SelectedDataKey["Did"].ToString();
}
所达到效果和前台绑定是一样的,楼主可以体会一下前台绑定和后台设置之间的差异,
这样和传统的都是用代码来搞定的一样了,当然设置断点调试就比较容易!



koukoujiayi 2010-04-29
  • 打赏
  • 举报
回复
ObjectDataSource是前台绑定的!如你的gv2绑定了gv1的select按钮,并接受Did传过来的值,
实现代码就是你的:
   <asp:ControlParameter ControlID="gv1" PropertyName="SelectedValue"
Type="Int64" Name="DId" />
</SelectParameters>


ObjectDataSource的好处就是大大减少后台代码!!
LT_Friends 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 koukoujiayi 的回复:]
引用 18 楼 lt_friends 的回复:

这个我知道的,但是现在的代码不是我写的,它本身就没有这个方法,所以我意思不能调试,当然,我刚才加了一下,就是按您说的双击事件自动成功,但是我想问……

如果后台没代码怎么调试?总要有后台代码吧!
没有gv1的SelectedIndexChanged事件,那就加上,调试完后再删掉!!
[/Quote]

这个真没有,所以我也纳闷呢。但是看到上面大家说的工作原理,大概明白了是怎么一回事
koukoujiayi 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 lt_friends 的回复:]

这个我知道的,但是现在的代码不是我写的,它本身就没有这个方法,所以我意思不能调试,当然,我刚才加了一下,就是按您说的双击事件自动成功,但是我想问……
[/Quote]
如果后台没代码怎么调试?总要有后台代码吧!
没有gv1的SelectedIndexChanged事件,那就加上,调试完后再删掉!!
LT_Friends 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 koukoujiayi 的回复:]
和楼上谈谈,
gv1绑定ObjectDataSource,gv1中有一个Select按钮,
完全可以在gv1的SelectedIndexChanged事件中获得值哦!!
怎么不可调试??
[/Quote]

这个我知道的,但是现在的代码不是我写的,它本身就没有这个方法,所以我意思不能调试,当然,我刚才加了一下,就是按您说的双击事件自动成功,但是我想问的是,这个代码本身没有select事件的情况。。。
阿非 2010-04-29
  • 打赏
  • 举报
回复
关于 ObjectDataSource ,我用的不多 ,不是很熟悉 ,以下观点仅供参考。

你的例子 要从 gv1 的 DataSourceID 说起

“如果设置数据绑定控件的 DataSourceID 属性,该控件根据需要自动绑定到数据源中的数据”

根据需要自动绑定到数据源中的数据 ,这里面就有两个疑问, 做了什么事, 什么时候做的

它调用了 Select() 方法 ,select 方法做了什么呢 看 #2

-----------------------------------------------------------
由 SelectMethod 属性标识的方法可能是一个实例方法或者一个 static(在 Visual Basic 中为 Shared)方法。 如果它是实例方法,除非使用同一实例调用由 SelectMethod 属性指定的方法和由 SelectCountMethod 属性指定的方法,否则,每次调用由 SelectMethod 属性指定的方法时,都会创建业务对象,然后损坏该对象。 Select 方法返回 IEnumerable 接口。 但是,若要启用缓存和筛选方案,返回值必须是 DataSet 对象。 虽然 DataSet 类不实现 IEnumerable 接口,但 ObjectDataSource 控件自动提取实现 IEnumerable 的默认 DataView 控件。
-------------------------------------------------------------------

简单的总结一下,就是 获取 SelectParameters 的全部参数(如果有的话),然后调用 SelectMethod 所指定的方法 ,把获取到的SelectParameters 全部参数 当做方法(SelectMethod 所指定的方法)的参数

是在什么时候做的这件事呢 ,我不确定,但可以确定的至少是在 PreRender 中 或之前

PreRender 是page 的事件之一,发生在 onload 之后
koukoujiayi 2010-04-29
  • 打赏
  • 举报
回复
将一个简单问题,搞很"高深"的模样,误导厉害哦!!
koukoujiayi 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 lt_friends 的回复:]

谢谢,我加了GridView1_SelectedIndexChanged事件,确实很明显的看出了取值情况,但是它那个代码里没有这个事件...
[/Quote]
没有这个事件,那就加这个事件,双击gv1就可以了!!
koukoujiayi 2010-04-29
  • 打赏
  • 举报
回复
和楼上谈谈,
gv1绑定ObjectDataSource,gv1中有一个Select按钮,
完全可以在gv1的SelectedIndexChanged事件中获得值哦!!
怎么不可调试??
LT_Friends 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 koukoujiayi 的回复:]
1.你的第二个gv的参数来自gv1的SelectedValue,
这是你在ods2中设置的!
代码体现:

<asp:ControlParameter ControlID="gv1" PropertyName="SelectedValue"
Type="Int64" Name="DId" />
</SelectParameters>
……
[/Quote]
谢谢,我加了GridView1_SelectedIndexChanged事件,确实很明显的看出了取值情况,但是它那个代码里没有这个事件...
LT_Friends 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 sandy945 的回复:]
每次调用 Select 方法时,ObjectDataSource 控件都检索数据。 [/Quote]

我的第三个问题就是想问第2个数据源是以什么方式监听或者叫检测第一个grivdviw的信息的?
您这句话是倒是能解释这个,但是我想是不是每次点击select,他都会跟服务器响应一次,相当于刷新页面了,既然刷新页面了,第2个数据源就能取到值了,就显示了?

vrhero 2010-04-29
  • 打赏
  • 举报
回复
1.当点击gv1的select linkButton时,它是怎么把DId值传给osd2的?是调用gv1.SelectedValue 取的值吗?但是我设过断点调试过,gv1.SelectedValue不是正确的值。(是在Page_Load设置断点的)
-------------------------------------
点击gv1的select linkButton时->浏览器把form元素中的值(包括客户端改变的和隐藏的ViewState)post到服务器...没有什么调用,服务器接收到这次request后解析form元素的值,同时参考ViewState数据还原Page对象,这次request在服务端叫做postback...

2.上述的过程是完全在.aspx页面写的,就是后台的cs代码里一点都没有,所以无法去调试。比如说点击select时,它到底是不是一个事件?
-------------------------------------
ASP.NET页面模型和Web服务器控件事件模型已经内建了相关的代码,你写的叫用户代码...点击select时还没有什么事件的概念,只是一个post request,参见1...

3.这个程序我写的话,会是把gv1的select做个事件,然后响应事件,再赋值给osd2,然后再绑定到gv2中。现在gv2是怎么监听select点击的?
-------------------------------------
参见MSDN ASP.NET Web服务器控件事件模型...
阿非 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 vrhero 的回复:]
再去看看ASP.NET页面模型和ASP.NET页面生存周期的概念,最后再去看看ASP.NET的Web服务器控件事件模型...
[/Quote]

v老师告诉你的这句话,就不是马上能说清楚的了

虽然可以罗列很多资料和文档,但你不能马上理解和消化。

还是先弄明白 get 与 post 的区别吧

阿非 2010-04-29
  • 打赏
  • 举报
回复
HTTP 协议 是无状态的
------------------

先记住这句话,它会困扰你一些日子。


http 协议 是 请求/响应模型 -> " request/response "

客户端给服务器发送请求, 服务器返回响应

请求的方式 有 get ,post ,put ,delete , head (还有什么忘记了)

常用的是 get 与 post

get 方式 参数在url 后面,请求时 url 是放在 请求头里的

而 post 方式 则是把参数 放在了 请求体中的
LT_Friends 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 vrhero 的回复:]

你要先学学HTTP协议,搞清楚get/post和request/response的概念,再去看看ASP.NET页面模型和ASP.NET页面生存周期的概念,最后再去看看ASP.NET的Web服务器控件事件模型...

[/Quote]

眼前来看的话,您能简单讲讲您上面所提到的知识吗?一两句话就成,还真不太明白
加载更多回复(7)

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧