冯东的博客

每天学一点,不断进取
posts - 75, comments - 268, trackbacks - 7, articles - 4
  博客园 :: 首页 :: 新随笔 ::  :: 订阅 订阅 :: 管理
FormView控件是可及显示、修改、添加、删除为一体的控件,感觉很好用,可是昨天发现了一个可以说是它的一个Bug吧,我是想要实现下拉框的联动效果,比如在A下拉框选择了省对应B的下拉框会把对应A中省的市显示在B下拉框中,我想要实现的是校区和对应校区建筑的联动效果,单纯的这种效果很好实现比如下面的代码
        <asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="SqlDataSource2"
            DataTextField
="校区简称" DataValueField="校区代码" AutoPostBack="true">
        
</asp:DropDownList>
        
<asp:DropDownList ID="DropDownList3" runat="server" DataSourceID="SqlDataSource3"
            DataTextField
="楼名称" DataValueField="楼代码">
        
</asp:DropDownList><asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:SBGLConnectionString %>"
            SelectCommand
="SELECT [楼名称], [楼代码] FROM [C_楼名代码表] WHERE ([校区] = @校区)">
            
<SelectParameters>
                
<asp:ControlParameter ControlID="DropDownList2" Name="校区" PropertyName="SelectedValue"
                    Type
="Int32" />
            
</SelectParameters>
        
</asp:SqlDataSource>
        
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:SBGLConnectionString %>"
            SelectCommand
="SELECT [校区代码], [校区简称] FROM [C_校区代码表]"></asp:SqlDataSource>
只需要这样就可以了,不用再CS中编写代码
但是把这个代码转移到FormView中就会出错,一般页面第一次载入时时不会出错的,我也不知道为什么,但是如果将校区换了以后就会出现下面的错误

Eval()、XPath() 和 Bind() 这类数据绑定方法只能在数据绑定控件的上下文中使用。

说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.InvalidOperationException: Eval()、XPath() 和 Bind() 这类数据绑定方法只能在数据绑定控件的上下文中使用。
源错误:

[没有相关的源行]

而且我还不知道是哪行错了,上网查了查,也有好多人问,但是没有人能给人正确或者说比较好的答案,我找了半天也没有找到解决办法,看来只能自己试一试了,差不多用了半天时间吧我已经能够实现想要实现的效果了,下面是我的代码,还请大家指点,哪如果有不足的地方请多指点

在ASPX文件中进行添加一个GridView然后对插入模板进行编辑实现校区下拉菜单和楼名的连动效果,这里需要注意以下几点:
1要实现连动要把校区下拉框的AutoPostBack属性设置为true;
2校区下拉框所对应的数据源孔件必须放在FormView里,否则回报错,找不到数据源
3对应校区的楼的下拉框的数据源空间要放到FormView的外面,实际上数据源和楼名下拉框基本上没有什么关系了,只是通过数据源获取数据然后把数据传递给DropDownList

        <asp:FormView ID="fv_ShiYanShi" runat="server" DefaultMode="Insert" Width="437px">
            
<InsertItemTemplate>
                
<asp:DropDownList ID="dpl_xiaoqu" runat="server" AutoPostBack="True" DataSourceID="sqd_xiaoqu"
                    DataTextField
="校区简称" DataValueField="校区代码" SelectedValue='<%# Bind("校区") %>'
                    Width="200px">
                
</asp:DropDownList><asp:SqlDataSource ID="sqd_xiaoqu" runat="server" ConnectionString="<%$ ConnectionStrings:SBGLConnectionString %>"
                    SelectCommand
="SELECT [校区代码], [校区简称] FROM [C_校区代码表]"></asp:SqlDataSource>
                
<asp:DropDownList ID="dpl_lou" runat="server" SelectedValue='<%# Bind("所在楼名") %>' Width="200px">
                
</asp:DropDownList>
            
</InsertItemTemplate>
        
</asp:FormView>
        
<asp:SqlDataSource ID="sqd_lou" runat="server" ConnectionString="<%$ ConnectionStrings:SBGLConnectionString %>"
            SelectCommand
="SELECT [楼代码], [楼名称], [校区] FROM [C_楼名代码表] WHERE ([校区] = @校区)" DataSourceMode="DataSet">
            
<SelectParameters>
                
<asp:Parameter Name="校区" Type="Int32" />
            
</SelectParameters>
        
</asp:SqlDataSource>
        
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:SBGLConnectionString %>"
            SelectCommand
="SELECT [楼代码], [楼名称] FROM [C_楼名代码表] WHERE ([校区] = @校区)" DataSourceMode="DataSet">
            
<SelectParameters>
                
<asp:Parameter Name="校区" Type="Int32" />
            
</SelectParameters>
        
</asp:SqlDataSource>
        
<asp:DropDownList ID="DropDownList1" runat="server">
        
</asp:DropDownList>

在对应的CS文件中这样进行处理

    private DropDownList dpl_xiaoqu;
    
private DropDownList dpl_lou;

    
protected void Page_Load(object sender, EventArgs e)
    
{
        dpl_xiaoqu 
= (DropDownList)this.fv_ShiYanShi.FindControl("dpl_xiaoqu");
        dpl_lou 
= (DropDownList)this.fv_ShiYanShi.FindControl("dpl_lou");
        dpl_xiaoqu_SelectedIndexChanged();
    }

    
protected void dpl_xiaoqu_SelectedIndexChanged()
    
{
        dpl_lou.Items.Clear();

        
this.sqd_lou.SelectParameters["校区"].DefaultValue = this.dpl_xiaoqu.SelectedValue;

        DataView datav 
= (DataView)this.sqd_lou.Select(DataSourceSelectArguments.Empty);
        
foreach (DataRowView dr in datav)
        
{
            ListItem li 
= new ListItem();
            li.Value 
= dr.Row["楼代码"].ToString();
            li.Text 
= dr.Row["楼名称"].ToString();
            dpl_lou.Items.Add(li);
        }

    }

Feedback

#1楼    回复  引用    

2007-01-23 16:56 by kokolc [未注册用户]
如果是三级联动呢?

#2楼    回复  引用  查看    

2007-07-19 09:20 by 阿牛      
如果三级联动,我这里有一个:
http://www.cnblogs.com/evlon/archive/2007/03/12/671468.html

#3楼    回复  引用    

2007-09-20 21:50 by yililing [未注册用户]
多谢楼主的指点
我刚入门2.0,以前没学过编程,都是看你的博客遍实践边学习,这次使用FormView用到下拉列表的联动,很是郁闷 看到你的文章 很有启发

可是我照你的方法 却出现了错误——系统提示如下:

未将对象引用设置到对象的实例——排错提示:使用“new”关键字创建对象实例;在调用方法前通过检查确定对象是否为空;

不明白怎么回事 google了两天 也没解决。。。 请教之!!!
万分感谢!

#4楼    回复  引用    

2007-09-20 22:02 by yililing [未注册用户]
哦 忘了详细说明了

我的问题出现在

dpl_lou.Items.Clear();

this.sqd_lou.SelectParameters["校区"].DefaultValue = this.dpl_xiaoqu.SelectedValue;

这两句上。。。 系统都是提示上面的同样的错误 不知道什么原因。。。

#5楼 [楼主]   回复  引用  查看    

2007-09-21 08:44 by 冯东      
@yililing
这个问题是我在VS2005里遇到的,如果你打了SP1补丁的时候就没问题了,我建议你打上VS2005的SP1。
对于出现“未将对象引用设置到对象的实例”这种问题,是因为你的对象没有初始化造成的,你在Page_Load或者在使用前进行初始化了吗?

#6楼    回复  引用    

2007-09-21 09:08 by yililing [未注册用户]
初始化是指下面的代码么?
private DropDownList dpl_xiaoqu;
private DropDownList dpl_lou;

protected void Page_Load(object sender, EventArgs e)
{
dpl_xiaoqu = (DropDownList)this.fv_ShiYanShi.FindControl("dpl_xiaoqu");
dpl_lou = (DropDownList)this.fv_ShiYanShi.FindControl("dpl_lou");
dpl_xiaoqu_SelectedIndexChanged();
}
已经写了的 :)

现在正在打SP1的补丁 谢谢楼主的指点!!! 继续向你学习!!!

#7楼 [楼主]   回复  引用  查看    

2007-09-21 11:09 by 冯东      
那就是初始化的过程没有取到值this.fv_ShiYanShi.FindControl("dpl_xiaoqu"); 的返回值是null,你用断点跟踪一下,fv_ShiYanShi是个FormView的实例,而dpl_xiaoqu是放在FormView的Edit Template里的一个DropdownList。

#8楼    回复  引用    

2007-09-21 19:39 by yililing [未注册用户]
感谢楼主指点 我装上SP1了 问题依然存在 我也认为是this.fv_ShiYanShi.FindControl("dpl_xiaoqu")的返回值是null,
但是,我不知道什么是断点追踪? :(

不知道要改动哪里? 代码是按照你的方法写的:
1.FormView 控件 fv_ShiYanShi 使用sqldatasource1自动绑定

2. fv_ShiYanShi的InsertItemTemplate 中对校区添加了一个dpl_xiaoqu, 并绑定sqd_xiaoqu,并且是自动回发
还有对楼号添加一个dpl_lou

3.在fv_ShiYanShi添加sql_lou

4.cs文件照你的代码写的

弄了两天了实在是不明白为什么返回值为NULL 不知道那错了 要怎么改
请指点!!! 非常感谢

#9楼    回复  引用    

2007-09-21 22:05 by yililing [未注册用户]
我又仔细看了楼主的帖子

发现问题出在这里 DefaultMode="Insert"
如果我 选择 ReadOnly 或者 Edit 执行的时候都会报错
改成 Insert (因为我的dpl放在 nsertItemTemplate 里面)就OK了!

#10楼 [楼主]   回复  引用  查看    

2007-09-22 08:05 by 冯东      
解决了就好,呵呵!

#11楼    回复  引用    

2007-09-22 10:00 by yililing [未注册用户]
可是 我想实现的是FormView能进行编辑、删除、插入功能,
现在却只能在DefaultMode="Insert" 模式下... ...
问题实际上还没完全解决 。。。。。。

#12楼 [楼主]   回复  引用  查看    

2007-09-23 20:48 by 冯东      
@yililing
FormView本身就有编辑、删除、和插入,因为我这没有VS.Net2005详细的设置我又忘了,你可以参考一下MSDN,另外,FormView也有个方法可以改变当前的状态,具体的方法名已经忘了。

#13楼    回复  引用    

2007-09-27 13:05 by yililing [未注册用户]
我又来了! 嘿嘿
多谢楼主指导,我自己尝试了在

DefaultMode="ReadOnly" 也就是默认的情况下
在CS文件中 Page_Load(object sender, EventArgs e)中加入逻辑判断

if (IsPostBack)
{
if (fv_ShiYanShi.CurrentMode == FormViewMode.Insert
{
dpl_xiaoqu_SelectedIndexChanged();
}
}
就可以在切换到插入模板的时候实现校区和楼名的二级联动了


不过我又现在录入了一些数据然后调试的时候发现了另一个问题:(
二级下拉列表现在可以显示,可是当楼名的下拉列表dpl_lou有多个选项(比如说1#楼、2#楼、3#楼等)的时候,只能将第一个选项(1#楼)录入数据库,
别的楼名即使是选中了,系统还是默认为为dpl_lou的第一行的楼名。。。。,也就是说只能是1#楼, 2#号楼、3#楼不能被选择,下拉列表都失去意义了。。。 不知道问题出在哪?

是我的数据库 SelectCommand的错误么? 我不知道。。。 请指教

#14楼 [楼主]   回复  引用  查看    

2007-09-27 20:48 by 冯东      
@yililing
我看了半天也没明白你说的什么意思,我觉得是这个意思:你选择一个楼,然后想把这个选择的楼的数据插入数据库,但是插入数据中的数据是第一个楼的数据,如果是这样的话是因为你在Page_Load函数里没有进行isPostBack判断,所以你点执行保存操作的时候又进行了一次数据绑定,所以是第一个数据插入了数据库。你需要根据IsPostBack来判断是否需要重新绑定DropDownList

#15楼    回复  引用    

2007-09-27 20:56 by yililing [未注册用户]
哦~~~~~~~

不好意思哈 说得你都晕了 不过 我明白你的意思了 我犯了一个基本的错误 我马上加上绑定的字段。

呵呵 多谢 多谢!!!

#16楼    回复  引用    

2007-10-11 17:25 by yuyang [未注册用户]
楼主你好,我根据你说的能够实现插入时的连动,但是在编辑的时候总是说楼区(及二级)有一个无效 SelectedValue,因为它不在项目列表中 。
请问这个问题怎么解决啊?

#17楼 [楼主]   回复  引用  查看    

2007-10-12 08:55 by 冯东      
@yuyang
我觉得是这样,你编辑的时候没有进行数据绑定,而根据viewState对DropdownList的数据还原的时候没有找到值,所以就出现了这个错误。
(猜的,不知道对不对)^_^

#18楼    回复  引用    

2007-10-18 08:46 by fdlmdark [未注册用户]
--引用--------------------------------------------------
yuyang: 楼主你好,我根据你说的能够实现插入时的连动,但是在编辑的时候总是说楼区(及二级)有一个无效 SelectedValue,因为它不在项目列表中 。
请问这个问题怎么解决啊?
--------------------------------------------------------
无效的可能是NULL吧。数据源UNION一个NULL进去应该就可以了。

#19楼    回复  引用    

2007-11-01 19:15 by yililing [未注册用户]
对于yuyang 的问题 估计是第一级下拉列表没有自动回发吧
看看AutoPostBack="true"加上了没?
或者是第二级下拉列表 要绑定数据库的一列 看加上了Bind("楼名称")没?


我的问题在14楼 好长时间忙别的事情了 现在又来请教 ^_^
foreach (DataRowView dr in datav)
{
ListItem li = new ListItem();
li.Value = dr.Row["楼代码"].ToString();
li.Text = dr.Row["楼名称"].ToString();
dpl_lou.Items.Add(li);
}
之后 是不是应该重新绑定第二级菜单? 怎么绑定?
如果不绑定 就会出现第二级菜单只有默认的第一个选项被选中并写入数据库 而别的选项怎么也不能被写入库里


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      


相关链接: