Fork me on GitHub
代码改变世界

WebForm控件多字段绑定

2016-06-25 13:33  沉睡的木木夕  阅读(686)  评论(0编辑  收藏  举报

一、这里的多字段绑定是什么意思?

多字段绑定控件其实就是把两个字段显示在一起作为一个字段现在控件上!

可能读者看了可能还是有点懵逼,说的还是比较抽象!的确,光从这上面的确是无法具体到某特定一种情况!那就直接上代码。

从标题上我们说的是古老的WebForm,咱暂且不论这个是否已经过时,既然遇到了,那就不能反抗吧......

代码如下:   

<!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></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater ID="Repeater1" runat="server">
            <ItemTemplate>
                <a href="#"><%#Eval("Id") %>-<%#Eval("Name")%></a>
            </ItemTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

 上面就是非常简单的服务器空间代码,其中的下划线代码段就是我之前说的多字段绑定

当然,这也是非常简单,非常舒服的一种绑定服务器控件的情况!这样不需要我们做过多的操作,就可以多字段绑定显示在UI上

那么问题就来了:

如果是那种只能一个字段绑定的控件呢?比如DropDownList,它的DataTextField以及DataValueField属性都只能绑定一个字段吧,它不能像Repeater那样灵活的绑定多个字段

那是不是就没法子了呢?肯定是有的,只不过我们等绕一绕,好,怎么绕?

现在我们的问题是下拉框控件只能绑定一个字段,那么我是不是只要新创建一个字段,这个字段的值是其他多字段的组合值不就行了么。

有了这个思路,代码就很容易写了

假使,我们的数据源是DataTable(也可以是IEnumerable)代码如下:

DataTable dt = new DataTable();
dt.Columns.Add("Id",Type.GetType("System.Int32"));
dt.Columns.Add("Name", Type.GetType("System.String"));
DataRow dr = dt.NewRow();
dr["Id"] = 1;
dr["Name"] = "Marson";
dt.Rows.Add(dr);
dr["Id"] = 2;
dr["Name"] = "Shine";
dt.Rows.Add(dr);

目前只能帮顶Id/Name字段中的一个,接着我们新建一个字段列

dt.Columns.Add("IdAndName", System.Type.GetType("System.String"));
dr = dt.NewRow();
foreach (DataRow item in dt.Rows)
{
    item["IdAndName"] = item["Id"].ToString() + "-" + item["Name"].ToString();
}    

这样我们就只需要绑定这个IdAndName就行了

这样代码感觉还是太多了,那有没有其他的方法呢?

其实有更简单,代码量更精简的方法,关键就在 DataColumn.Expression 这个属性上

它用于筛选行、计算列中的值或创建聚合列 也支持字符串的一般拼接,多字段的拼接(注:用单引号连接,MDSN上有详细说明)

那么有了这个,于是就有了下面的代码段:

dt.Columns.Add("IdAndName", System.Type.GetType("System.String"), "Id+'-'+Name");
View Code

这样是不是更精简了呢?

如果对DataColumn.Expression有兴趣的同学,可以反编译查看是如何实现上面MSDN介绍的那些功能的

我大概的看了下,真是一脸懵逼啊,那些代码我就不知道什么意思,像下面这些 我还是没怎么看懂,功夫没到家啊

Bid.ScopeEnter(out intPtr, "<ds.DataColumn.set_Expression|API> %d#, '%ls'\n", this.ObjectID, value);
Bid.ScopeLeave(ref intPtr);
以及核心赋值Expression代码段
public DataColumn(string columnName, Type dataType, string expr, MappingType type) {
            GC.SuppressFinalize(this);
            Bid.Trace("<ds.DataColumn.DataColumn|API> %d#, columnName='%ls', expr='%ls', type=%d{ds.MappingType}\n",
                          ObjectID, columnName, expr, (int)type);
 
            if (dataType == null) {
                throw ExceptionBuilder.ArgumentNull("dataType");
            }
 
            StorageType typeCode = DataStorage.GetStorageType(dataType);
            if (DataStorage.ImplementsINullableValue(typeCode, dataType)) {
                throw ExceptionBuilder.ColumnTypeNotSupported();
            }
            _columnName = columnName ?? string.Empty;
 
            SimpleType stype = SimpleType.CreateSimpleType(typeCode, dataType);
            if (null != stype) {
                this.SimpleType = stype;
            }
            UpdateColumnType(dataType, typeCode);
 
            if ((null != expr) && (0 < expr.Length)) {
                // @perfnote: its a performance hit to set Expression to the empty str when we know it will come out null
                this.Expression = expr;
            }
            this.columnMapping = type;
        }

有童鞋知道的,告诉我下,谢谢!