文本框数据绑定

7
当使用WebForms处理事务时,页面上往往会出现大量的文本框,这意味着你也往往需要编写前后端数据绑定的代码:
tbMyTextBox.Text = MyViewObjectDataClass.MyStringProperty;

并且

MyViewObjectDataClass.MyStringProperty = tbMyTextBox.Text;

这个过程可能会变得很重复......

我可以使用AutoMapper自动映射我的视图对象和域对象,这引出了一个问题......

有没有办法自动将ASP.Net表单元素转换为视图对象?而不是使用上面的几行代码?

是的,我可以切换到MVC,但对于许多正在进行的项目来说,这不是一个选择。


ASP.NET Web Forms vNext将拥有这个功能。http://weblogs.asp.net/scottgu/archive/2011/09/05/web-forms-model-binding-part-1-selecting-data-asp-net-vnext-series.aspx - CheckRaise
4个回答

7
在ASPX文件中,采用这种方法如何?
<asp:TextBox ID="TextBox1" runat="server" Text='<%#MyViewObjectDataClass.Name %>'></asp:TextBox>

但是,我们仍然需要添加语句:

  protected void Page_Load(object sender, EventArgs e)
  {
         if (!Page.IsPostBack)
         {
          this.DataBind();
         }
  }

另一种方法是使用自定义控件,如下所示:

            public class NullPanel : Panel
            {
                private bool _autoBind = true;

                public override void RenderBeginTag(System.Web.UI.HtmlTextWriter writer)
                {
                    //base.RenderBeginTag(writer);
                }

                public override void RenderEndTag(System.Web.UI.HtmlTextWriter writer)
                {
                    //base.RenderEndTag(writer);
                }

                protected override System.Web.UI.HtmlTextWriterTag TagKey
                {
                    get
                    {
                        return System.Web.UI.HtmlTextWriterTag.Unknown;
                    }
                }

                [DefaultValue(true)]
                public bool AutoBind
                {
                    get
                    {
                        return _autoBind;
                    }
                    set
                    {
                        _autoBind = value;
                    }
                }

                protected override void OnLoad(EventArgs e)
                {
                    base.OnLoad(e);
                    //Set Visible property as true that intent to rise OnPreRender method
                    this.Visible = true;
                }

                protected override void DataBindChildren()
                {
                    if (this.Visible && this.AutoBind)
                    {
                        base.DataBindChildren();
                    }
                }

                protected override void OnPreRender(EventArgs e)
                {
                    if (this.AutoBind)
                    {
                        this.DataBind();
                    }
                    base.OnPreRender(e);
                }
            }

然后在ASPX文件中使用它:

 <asp:NullPanel ID="panelFenInfo" runat="server" 
         Visible='<%#this.IsEditMode%>' >
   <asp:TextBox ID="tbName" runat="server" Text='<%#this.MyViewObjectDataClass.Name %>'></asp:TextBox>
 <asp:NullPanel>
 <asp:NullPanel ID="panelInfo" runat="server" 
         Visible='<%#!Page.IsPostBack%>' >
   <asp:TextBox ID="tbCompany" runat="server" Text='<%#this.MyViewObjectDataClass.Name %>'></asp:TextBox>
 <asp:NullPanel>

1
感谢这个 this.DataBind() 的提示! - box86rowh

0

在 .aspx 文件中直接数据绑定文本框:

<asp:repeater id="rptRem" runat="server" datasourceid="ObjectDataSource_ValidTicket">
     <itemTemplate>
           <asp:TextBox ID="TextBox_v_rem" runat="server" MaxLength="650" Width="100%" Text='<%# Eval("v_rem") %>' />
     </itemTemplate>
</asp:repeater>

0
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Lib
{
public class MVAchiever<T>
{
    private T model;
    public T PullData(string ServerClass, Control cr)
    {
        model = (T)Activator.CreateInstance(typeof(T));
        if (cr.HasControls())
        {
            loopControl(cr, ServerClass);
        }
        return model;
    }
    private void loopControl(Control cr, string ServerClass)
    {
        foreach (Control c in cr.Controls)
        {
            if (c is WebControl)
            {
                WebControl wc = (WebControl)c;
                getThisDataFrom(wc, ServerClass);
            }
            if (c.HasControls())
            {
                loopControl(c, ServerClass);
            }
        }
    }
    private void getThisDataFrom(WebControl wc, string ServerClass)
    {
        string className = wc.Attributes["ServerClass"];
        string propName = wc.Attributes["ServerProperty"];
        string val = "";
        if (className == ServerClass && !string.IsNullOrEmpty(propName))
        {
            if (wc is DropDownList)
            {
                val = ((DropDownList)wc).SelectedValue;
            }
            else if (wc is TextBox)
            {
                val = ((TextBox)wc).Text;
            }                
            PropertyInfo pi = typeof(T).GetProperty(propName);
            Type pt = pi.PropertyType;
            if (!string.IsNullOrEmpty(val) && TypeDescriptor.GetConverter(pt).IsValid(val))
            {
                pi.SetValue(model, Convert.ChangeType(val, pt));
            }
        }
    }
}
}

使用方法

ASP:

<asp:TextBox ID="TextBox1" runat="server" ServerClass="Model" ServerProperty="PropertyName"></asp:TextBox>

C#:

Model m = new MVAchiever<Model>().PullData("Model", Panel);

您可以添加任意数量的不同WebControls,我只使用了上述两个。


0

那个链接已经失效了,但我认为这是同一篇文章的镜像:http://www.west-wind.com/presentations/aspnetdatabinding/aspnetdatabinding.asp - Stefan Mohr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接