开发者

Textbox data binding

开发者 https://www.devze.com 2023-03-18 08:05 出处:网络
When using WebForms for stuff, you tend to end up with a lot of textboxes on the page, which means you also tend to end up with the back and forth data binding code:

When using WebForms for stuff, you tend to end up with a lot of textboxes on the page, which means you also tend to end up with the back and forth data binding code:

tbMyTextBox.Text = MyViewObjectDataClass.MyStringProperty;

and

MyViewObjectDataClass.MyStringProperty 开发者_运维百科= tbMyTextBox.Text;

This can get quite repetitive....

I can automate the mappings between my view object and my domain object using AutoMapper, which leads me to the question...

Is there any way to do the ASP.Net form element to view object automagically? Without resorting to dozens of the above lines?

Yes, I could just switch to MVC, but that isn't an option for a lot of ongoing projects.


How about this approach in ASPX files:

<asp:TextBox ID="TextBox1" runat="server" Text='<%#MyViewObjectDataClass.Name %>'></asp:TextBox>

But we still need to add statements:

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

Another approach use a custom control like this:

            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);
                }
            }

Then use it in ASPX files:

 <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>


You might want to check this post by Rick Strahl about supply two-way binding http://msdn.microsoft.com/en-gb/magazine/cc163505.aspx


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));
            }
        }
    }
}
}

Usage

ASP:

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

C#:

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

You can add as many different WebControls as you like, I stuck with the two above.


Directly data bind a textbox in .aspx file:

<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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号