zoukankan      html  css  js  c++  java
  • 绑定Enum到ASP.NET数据绑定控件的完美解决方案[05/26修订]——增加支持第三方枚举描述,支持二进制与过的枚举值

    本文向读者介绍NBear中实现的DropDownListField字段绑定控件和EnumDescriptionAttribute特性。结合使用这两个组件,就可以最简单、易用和可扩展地完美解决绑定Enum到ASP.NET数据绑定控件的问题。[05/26修订]——增加支持第三方枚举描述,支持二进制与过的枚举值。

    从DropDownListField的名称,大家一定猜到了,是的,DropDownListField控件和ASP.NET内置的BoundField,CheckBoxField等一样,可以直接用于GridView,DetailsView等控件的声明中,用于描述一个Enum类型的字段的绑定。使用DropDownListField,我们就再也不需要向原来一样为了绑定一个Enum类型的值而使用自定义ItemTemplate并嵌入DropDownList,并写额外代码来填充ItemTemplate中的DropDownList了。

    首先,我们看看如何在我们的页面代码中使用DropDownListField控件:

     1<%@ Page Language="C#" %>
     2<%@ Register TagPrefix="nb" Namespace="NBear.Web.Data" Assembly="NBear.Web.Data" %>
     3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     4<html xmlns="http://www.w3.org/1999/xhtml" >
     5<head runat="server">
     6    <title>NBear DataSource Test</title>
     7</head>
     8<body>
     9<form id="aspnetForm" runat="server">
    10    <nb:NBearDataSource ID="TestDS" runat="server" ConnectionStringName="test access db"
    11        TypeName="Entities.SimpleData" FilterExpression="{SimpleID} > 0" DefaultOrderByExpression="{SimpleID} DESC, {SimpleName}" />
    12    <asp:GridView ID="TestGrid" runat="server" DataSourceID="TestDS" AllowSorting="True" AllowPaging="True"
    13        PageSize="3" AutoGenerateEditButton="True" AutoGenerateDeleteButton="True" DataKeyNames="SimpleId" AutoGenerateColumns="False" >
    14        <Columns>
    15            <asp:BoundField DataField="SimpleId" HeaderText="SimpleId" SortExpression="SimpleId" />
    16            <asp:BoundField DataField="SimpleName" HeaderText="SimpleName" SortExpression="SimpleName" />
    17            <asp:CheckBoxField DataField="BoolVal" HeaderText="BoolVal" SortExpression="BoolVal"
    18                Text="BoolVal" />
    19            <nb:DropDownListField DataField="Status" HeaderText="Status" SortExpression="Status" EnumType="EntityDesigns.SimpleStatus" />
    20        </Columns>
    21    </asp:GridView>
    22    <br />
    23    <asp:DetailsView ID="TestDetail" runat="server" DataSourceID="TestDS" DefaultMode="Insert"
    24            AutoGenerateInsertButton="True" AutoGenerateRows="False">
    25        <Fields><asp:BoundField DataField="SimpleName" HeaderText="Name" />
    26            <asp:CheckBoxField DataField="BoolVal" HeaderText="BoolVal" />
    27            <nb:DropDownListField DataField="Status" HeaderText="Status" EnumType="EntityDesigns.SimpleStatus" />
    28        </Fields>
    29    </asp:DetailsView>
    30</form>
    31</body>
    32</html>

    请注意第2和第19,27行。在页面中,首先要注册NBear.Web.Data命名空间。接着,在数据控件的Columns中,添加DropDownListField就行了,和ASP.NET内置的的CheckBoxField使用中的唯一区别是,DropDownListField必须额外设置一个EnumType属性,顾名思义,就是绑定到这个控件Enum字段的类型的FullName。

    OK,就是这么简单。本页面中使用到的SimpleStatus如下:

    1    public enum SimpleStatus
    2    {
    3        Value1 = 1,
    4        Value2 = 2
    5    }

    如果运行这个页面,您将可以看到DropDownList中显示的是Value1和Value2。

    -

    等1秒钟,你一定要说,这还不是我想要的,因为,我需要枚举值在DropDownList中显示的文字描述是我需要的自定义信息。

    OK,接着就轮到本文的第二个主角——EnumDescriptionAttribute了。

    只需要如下使用EnumDescriptionAttribute标注Value1和Value2就行:

    1    public enum SimpleStatus
    2    {
    3        [NBear.Common.EnumDescription(DefaultDescription="Desc of Value1")]
    4        Value1 = 1,
    5        [NBear.Common.EnumDescription(DefaultDescription="Desc of Value2")]
    6        Value2 = 2
    7    }

    OK,不需要任何额外设置了,再运行上面的页面,您将能看到DropDownList中显示的文字是我们指定的自定义信息了。很酷不是吗?

    -

    再等一秒钟,我们还是不会满足的,虽然我们可以指定自定义说明信息,但是,如果是多语言环境,我们需要运行时对枚举值的显示不同的文字信息,还有很多情况,我们需要从数据库中的枚举描述表读取对枚举的描述信息。

    对此,我们当然也提供了解决方案。

    我们只需要继承EnumDescriptionAttribute即可。下面的MyEnumDescriptionAttribute演示了一个自定义的枚举描述实现:

    1    public class MyEnumDescriptionAttribute : NBear.Common.EnumDescriptionAttribute
    2    {
    3        private static string[] customDescs = new string[] "custom desc of Value1"null };    //the second value is null here to use the DefaultDescription set in enum definition
    4
    5        public override string GetDescription(object enumValue)
    6        {
    7            return customDescs[(int)enumValue] ?? base.GetDescription(enumValue);
    8        }

    9    }

    这个类重载了EnumDescriptionAttribute的GetDescription()方法,从一个内存中的数组中读取描述信息。类似的,我们也可以在这里从资源文件或者数据库中读取说明信息,都只需要重载这个方法就可以了。

    您一定注意到其中的注释代码了,假如,对某个枚举值,我们的自定义方法取不到自定义的描述信息,那么,它会首先查看对这个枚举值标注的MyEnumDescriptionAttribute有没有指定DefaultDescription,如果制定则返回这个内容,否则就返回枚举值的ToString()内容。

    使用MyEnumDescriptionAttribute描述SimpleStatus如下:

    1    public enum SimpleStatus
    2    {
    3        [MyEnumDescription(DefaultDescription="Default Desc of Value1")]
    4        Value1 = 1,
    5        [MyEnumDescription(DefaultDescription="Default Desc of Value2")]
    6        Value2 = 2
    7    }


    再次运行页面,您将看到,DropDownList中对应Value1显示的信息为custom desc of Value1,而对应Value2显示的信息为Default Desc of Value2。为什么呢?因为对Value1我们能取到MyEnumDescriptionAttribute返回的自定义信息,而对Value2,MyEnumDescriptionAttribute返回null,那么,默认的描述信息将被应用。是不是很神奇呢?

    甚至,您可以对同一个Enum类型的不同成员项混合使用不同的EnumDescriptionAttribute或其继承类来指定描述信息(有这样的需求吗^-^)。但是,每个枚举项只有第一个EnumDescriptionAttribute或其继承类标注会生效,多余的标注会被忽略。

     好了,基本介绍完了,斗胆称这个方案为完美方案,别扔臭鸡蛋就好。:)


    篇后语

    除了结合数据绑定控件使用EnumDescriptionAttribute之外,您也可以单独使用EnumDescriptionAttribute以透明获取的枚举值描述信息。调用EnumDescriptionAttribute.GetDescriptions(enumType)这个静态方法就可以得到指定枚举类型的所有枚举值的由EnumDescriptionAttribute或其继承类标注的描述信息。

    DropDownListField类是参考ASP.NET内置的CheckBoxField类写的。


    下载

    本文介绍的组件的全部源码和示例代码包含于最新版本的nbear中,EnumDescriptionAttribute定义于src\NBear.Common\EnumDescriptionAttribute.cs,DropDownListField定义于src\NBear.Web.Data\DropDownListField。示例程序位于tutorials\NBearDataSourceSample。

    可以从NBear的官方网站下载:http://nbear.org

    -

    [05/26修订]——增加支持第三方枚举描述,支持二进制与过的枚举值。包含于NBearV3.7.1 build 7以上版本。

    1、对于在第三方已编译程序集中的枚举类型,也就是说我们没有机会直接添加EnumDescriptionAttribute到枚举定义的,现在也支持了。只需要额外定义一个与外部枚举类型对应的枚举类型,保证两个枚举类型的枚举项的int值相等即可,在这个新枚举类型中标注EnumDescriptionAttribute即可。当然,此时,EnumType属性需要填新的枚举类型名称。

    2、对于枚举值支持二进制与的枚举值,现在也支持了,无需额外设置。不过这种枚举值的insert和edit如果需要更新为合并值,还是需要用户自行写代码完成。这里仅仅是支持到显示这样的值。

    //本文结束



  • 相关阅读:
    Qt的网络通信(以一对一聊天室为例)
    C/C++中的const ,static
    Qt的认识与相关问题的解决
    Qt的简单介绍,发展和由来
    STL模板的基础与了解
    malloc与new,C++中的指针与引用,C++struct与class的区别
    Qt的常用控件及控件的使用
    Qt的环境与工具、信号与槽
    学习Qt前你需要知道的
    模板与STL小结--vector、list、map等各类容器
  • 原文地址:https://www.cnblogs.com/teddyma/p/759842.html
Copyright © 2011-2022 走看看