惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
博客园 - Franky
J
Java Code Geeks
V
Visual Studio Blog
G
Google Developers Blog
罗磊的独立博客
MongoDB | Blog
MongoDB | Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Recent Announcements
Recent Announcements
Last Week in AI
Last Week in AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Stack Overflow Blog
Stack Overflow Blog
博客园 - 司徒正美
The GitHub Blog
The GitHub Blog
腾讯CDC
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
博客园 - 【当耐特】
IT之家
IT之家
I
InfoQ
U
Unit 42
C
Check Point Blog
Martin Fowler
Martin Fowler

博客园 - 阿福

TypeScript forms authentication failed the ticket supplied was invalid错误 (Windows Server 2008 + IIS 7.5) jQuery Mobile 1.1.1 RC1发布 HashSet<T> vs List<T> 不要用把无序GUID既作为主键又作为聚集索引 WCF Data Services 5.0 RTM发布 EF Power Tools Beta 2发布 Entity Framework 5性能方面的注意事项 jQuery Mobile 1.1.0 RC2发布 源码+幻灯片:学习HTML5/jQuery/ASP.NET MVC/EF Code First的绝佳资源Account at a Glance项目 使用Autofac在ASP.NET Web API上实现依赖注入 在Windows Azure上开发ASP.NET程序与在Windows Sever上有何不同 充分利用缓存来提高网站性能 ASP.NET MVC 4, ASP.NET Web API, ASP.NET Web Pages v2 (Razor)全部开源,并接受来自社区的贡献(contributions) EF5 beta2通过NuGet发布 Getting Started with HTML5 开发HTML5应用你需要了解的 WCF入门资源 jquery history plugin, url hash Run Tasks in an ASP.NET Application Domain ASP.NET 2.0: 生成Excel报表 VS 2008 hot-fix终于出来了 Images; How to create an HTTP handler to dynamically resize images and change quality. ASP.NET 2.0: Add build-in paging feature to repeater/为repeater添加内置分页功能 ASP.NET 2.0: Forms Authentication Across domains Ajax类库、框架、工具包完全列表 怀旧啊 Search Box ASP.NET 2.0: Site Maps Checking All CheckBoxes in a GridView
Tip/Trick ASP.NET 2.0: DropDow...
阿福 · 2010-01-01 · via 博客园 - 阿福

问题

用DropDowList输入参照数据时,例如输入产品信息时,选择产品类别,通常情况下产品类别也应该是从数据库中绑定出来的。这时会用两个问题:

  1. 如何方便的在DropDownList里放入一个空值,即Value为空字符串的一个ListItem,因为数据源中是不存在空值的;
  2. 当编辑某个产品信息时,如果该条产品信息的类别信息已经删除,那么在编辑视图绑定数据时,DropDownList就会报错,因为此时DropDownList的Items集合中 并不存在值为SelectedValue的Item。其实这是个数据一致性的问题。

办法

解决问题1需要利用DropDownList的AppendDataBoundItems属性,这个属性在ASP.NET 1.x是好像是没有的,所以在2.0中一直也没注意到,直到一天才偶然发现。顾名思义,这个属性的作用就是把绑定产生的Items附加到原有Items的后面。那么,解决问题1,我们就可以先在页面里显性声明一个静态的ListItem,如:<asp:ListItem Value="">None</asp:ListItem>,然后将DropDownList的AppendDataBoundItems属性设为true(默认值为false),完整代码实例看下方。

解决问题2,需要对DropDownList做一些必要的扩展,因为在问题2所处的情况下,DropDownList的默认行为就是抛出一个异常,我们的目的是使其具有"容错"功能,在SelectedValue不存在的情况下,默认选择第一项,也就是空值项。通过对DropDownList源码的研究,我们发现这个异常是在执行PerformDataBinding 方法时抛出的,那么最简单的方法就是重写改方法,吃掉抛出的异常,代码片段见下方。

aspx代码片段:
            <asp:FormView ID="FormViewProductDetail" runat="server" DataKeyNames="PurchaseOrderID"
                DataSourceID="SqlDataSourceProduct" Width="100%">
                <EditItemTemplate>
                    <table cellpadding="0" cellspacing="0" width="100%" border="0">
                        <tbody>
                            <tr class="alternating">
                                <td>
                                    <asp:Label ID="Label1" runat="server" Text="Product Name"></asp:Label>
                                </td>
                                <td>
                                    <asp:TextBox ID="ProductNameTextBox" runat="server" Text='<%# Bind("ProductName") %>'>
                                    </asp:TextBox>
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    <asp:Label ID="Label8" runat="server" Text="Category"></asp:Label></td>
                                <td>
                                    <ts:DropDownList ID="DropDownListCategory" runat="server" AppendDataBoundItems="True"
                                        DataSourceID="SqlDataSource1" SelectedValue='<%# Bind("CategoryID") %>' DataTextField="CategoryName"
                                        DataValueField="CategoryID">
                                        <asp:ListItem Value="">None</asp:ListItem>
                                    </ts:DropDownList>
                                    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:MyConnectionString %>"
                                        SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Category]"></asp:SqlDataSource>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </EditItemTemplate>
                ......Other Template.........
            </asp:FormView>

DropDownList扩展:
    public class DropDownList : System.Web.UI.WebControls.DropDownList
    {

        /// 

        /// kill the exception. the exception was raised because the selectedvalue does not exist in the list items, 

        /// we do not hope the control throws a "selectedvalue not exist..." exception

        /// 

        /// 

        protected override void PerformDataBinding(System.Collections.IEnumerable dataSource)

        {

            try

            {

                base.PerformDataBinding(dataSource);

            }

            catch (ArgumentOutOfRangeException ex)

            {

                ArgumentOutOfRangeException o = ex;

            }

        }

    }