在Controls文件夹中建立一个名为UserProfile.ascx的用户控件,其中包含了用户界面和对用户资料进行显示和更新的业务逻辑。

 

UserProfile.ascx的设计视图代码如下:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="UserProfile.ascx.cs" Inherits="成员配置系统.Controls.UserProfile" %>
<table cellpadding="2">
   <tr>
      <td style="width: 110px;" class="fieldname">姓名:</td>
      <td style="width: 400px;"><asp:TextBox ID="txtFirstName" runat="server" Width="99%"></asp:TextBox></td>
   </tr>
   <tr><td>爱好:</td><td>
       <asp:DropDownList ID="ddlHobbys" runat="server">
       </asp:DropDownList></td></tr>
   <tr><td class="fieldname">性别:</td>
      <td>
         <asp:DropDownList runat="server" ID="ddlGenders">
            <asp:ListItem Text="请选择..." Value="" Selected="True" />
            <asp:ListItem Text="男" Value="M" /> <asp:ListItem Text="女" Value="F" />
         </asp:DropDownList></td></tr>
   <tr>
      <td class="fieldname">出生日期:</td> <td>
         <asp:TextBox ID="txtBirthDate" runat="server" Width="99%"></asp:TextBox>
         <asp:CompareValidator runat="server" ID="valBirthDateType" ControlToValidate="txtBirthDate"
            SetFocusOnError="true" Display="Dynamic" Operator="DataTypeCheck" Type="Date"
            ErrorMessage="日期格式不对!" ToolTip="The format of the birth date is not valid."
            ValidationGroup="EditProfile"><br />日期格式不对!</asp:CompareValidator></td></tr>
      <tr><td class="fieldname">城市:</td>
      <td><asp:TextBox runat="server" ID="txtCity" Width="425px" /></td></tr>
   <tr> <td class="fieldname">省份:</td><td>
          <asp:DropDownList ID="ddlProvinces" runat="server" AppendDataBoundItems="True"
              Width="410px" Height="22px">
            <asp:ListItem Text="请选择..." Value="" Selected="True" />
         </asp:DropDownList></td></tr>
</table>

自己定义一个爱好的枚举类型Hobby,见代码:

namespace 成员配置系统
{
      public enum Hobby : int {
         唱歌=0,
            体育 =1,
            写作
        }
}

可以看到,其中包含了一个DropDownList控件,可以让用户选择自己所属的省份。由于这个下拉框其它页面也需要,在业务组件中也需要它,所以该控件不能进行硬编码,通过一个辅助(helper)方法将省份列表作为一个字符串数组传递过来。

public static class Helpers
    {
        private static string[] _provinces = { "北京市", "天津市", "安徽省", "辽宁省", "四川省", "青海省", "甘肃省" };
        public static List<string> GetProvinces()
        {
            List<string> provinces = new List<string>();
            provinces.AddRange(_provinces);
            return provinces;
        }
 
    }

DropDownList控件的AppendDataBoundItems属性设置为true,用户控件中没有Submit按钮。(该按钮由宿主页面[hostPage]提供)

1.在新的控件状态中保持属性

   由于在管理部分会使用该控件来读取和编辑用户资料,所以需要一个公共属性来保存要查询的用户名。

 

如果将需要的属性值保存在View state(视图状态)中,好处是不需要使用服务器端的资源来保存临时值,而是作为页面的一部分保存的。

用户通过浏览器每次回送时,该隐藏值都会同表单的其他数据一起回送给服务器。但是有个问题:

通过设置页面或者控件的EnableViewState属性为False,可以将视图状态为禁用状态。(禁用是为了减少网络中数据传送量的常用方法),

使用视图状态来保存数据的控件在视图状态禁用时无法在特定的宿主页面上正常工作。

ASP.NET2.0引入了新的状态类型,称为控件状态(control state),它只与特定控件相关,并且不能被禁用。

为了使用它,需要完成以下事情:

1:定义属性,该属性需要一个关联的私有字段

2:控件的Init事件处理程序来调用宿主页面(父页面)的RegisterRequiresControlState方法。

3:控件的SaveControlState方法重写,返回用户保存控制状态的对象数组。

4:重写LoadControlState方法:将对象的输入数组进行分解,使用数组中的值将属性的私有字段初始化。

见代码:

public partial class UserProfile : System.Web.UI.UserControl
   {
      private string _userName = "";//使用控件状态的第一步:定义属性,该属性需要一个关联的私有字段
      public string UserName
      {
         get { return _userName; }
         set { _userName = value; }
      }
 
      //使用控件状态的第二步:控件的Init事件处理程序来调用宿主页面(父页面)的RegisterRequiresControlState方法。
      protected void Page_Init(object sender, EventArgs e)
      {
          this.Page.RegisterRequiresControlState(this);
          //将控件注册为具有持久性控件状态的控件,通知页面,本控件需要保存一些控制状态信息
      }
 
      //使用控件状态的第三步: 控件的SaveControlState方法重写,返回用户保存控制状态的对象数组。
      protected override object SaveControlState() //返回用户保存控制状态的对象数组。
      {
          object[] ctlState = new object[2];
          ctlState[0] = base.SaveControlState();
          ctlState[1] = _userName;
          return ctlState; //数组中除了要保持的属性值外,还要包含其基类的控制状态
      }
 
      //使用控件状态的第四步:重写LoadControlState方法
      protected override void LoadControlState(object savedState)
      {
          object[] ctlState = (object[])savedState;
          base.LoadControlState(ctlState[0]); //将对象的输入数组进行分解
          _userName = (string)ctlState[1];  //使用数组中的值将属性的私有字段初始化
      }

2.对用户资料进行加载和编辑

protected void Page_Load(object sender, EventArgs e)
      {
         if (!this.IsPostBack)
         {
             //对用户资料进行加载
             ddlProvinces.DataSource = Helpers.GetProvinces();
             ddlProvinces.DataBind();
             ProfileCommon profile = this.Profile;
             if (this.UserName.Length > 0) profile = this.Profile.GetProfile(this.UserName);
 
             ddlGenders.SelectedValue = profile.Gender;
             ddlHobbys.SelectedValue = profile.Hobby.ToString();
             ddlProvinces.SelectedValue = profile.Address.Province;
 
             txtBirthDate.Text = profile.BirthDate.ToShortDateString();
             txtCity.Text = profile.Address.City;
             txtFirstName.Text = profile.UserName;
         }
      }
 
      public void SaveProfile()
      {
          //对用户资料进行编辑
          ProfileCommon profile = this.Profile;
          if (this.UserName.Length > 0) profile = this.Profile.GetProfile(this.UserName);
 
          profile.Gender = ddlGenders.SelectedValue;
          profile.Hobby = (Hobby)Enum.Parse(typeof(Hobby),ddlHobbys.SelectedValue);
          profile.Address.Province = ddlProvinces.SelectedValue;
          profile.BirthDate = DateTime.Parse(txtBirthDate.Text);
          profile.Address.City = txtCity.Text;
          profile.UserName = txtFirstName.Text;
 
          profile.Save();//一定不要忘记
           
      }

3:注册页面

回到以前的CreateUserWizardDemo.aspx页面(参考博客:图形登录控件 http://www.cnblogs.com/netxiaochong/archive/2011/12/25/2301024.html)

在CreateUserWizard控件的<WizardSteps>增加自己的步骤:填写用户配置的信息(已经封装在UserProfile控件),改动如下:

 

 

页面的后台代码文件很短,只需要处理用户注册向导中的FinishButtonClick事件,让它调用UserProfile的SaveProfile方法。

public partial class CreateUserWizardDemo : System.Web.UI.Page
    {
        protected void CreateUserWizard1_FinishButtonClick(object sender, WizardNavigationEventArgs e)
        {
            UserProfile1.SaveProfile();//保存用户配置信息
        }

运行CreateUserWizardDemo.aspx,看看效果:

 

这里展现了向导中的第二步,允许用户设置自己的个人资料!