【问题标题】:How to maintain user control values in view state?如何在视图状态下维护用户控件值?
【发布时间】:2013-09-27 11:42:33
【问题描述】:

我想在视图状态下维护用户控件值

我试过文本框,下拉值保持在视图状态

但 BasicDatePicker 值未在视图状态下保持我得到空值

代码:

.aspx

<asp:Repeater ID="rpt1" runat="server">
<ItemTemplate>
</ItemTemplate>
</asp:Repeater>
<asp:Button ID="addnewtext" runat="server" Text="Add" onclick="addnewtext_Click"  width="76px" />
<asp:Button ID="btnSaveVisa" Text="Save" runat="server" OnClick="btnSaveVisa_Click" /> 

.aspx.cs

 private const string VIEWSTATEKEY = "ContactCount";
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            //Set the number of default controls
            ViewState[VIEWSTATEKEY] = ViewState[VIEWSTATEKEY] == null ? 1 : ViewState[VIEWSTATEKEY];

            //Load the contact control based on Vewstate key
            LoadContactControls();
        }
    }

    protected override void LoadViewState(object savedState)
    {
        base.LoadViewState(savedState);

        LoadContactControls();
    }


    private void LoadContactControls()
    {
        for (int i = 0; i < int.Parse(ViewState[VIEWSTATEKEY].ToString()); i++)
        {
          rpt1.Controls.Add(LoadControl("AddVisaControl.ascx"));
        }
    }

    protected void addnewtext_Click(object sender, EventArgs e)
    {
        LoadContactControls();
        ViewState[VIEWSTATEKEY] = int.Parse(ViewState[VIEWSTATEKEY].ToString()) + 1;

    }
    private void saveData()
    {
        foreach (var control in rpt1.Controls)
        {
            var usercontrol = control as AddVisaControl;

            string s = usercontrol.TextVisaNumber;
            string date = usercontrol.ExpiryDate.ToShortDateString();
        }
    }

    protected void Save_Click(object sender, EventArgs e)
    {
        saveData();
    }
   }

.ascx

这里我添加了 BasicDatePicker 的程序集

   <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AddVisaControl.ascx.cs" EnableViewState="false" Inherits="Pyramid.AddVisaControl" %>
   <%@ Register assembly="BasicFrame.WebControls.BasicDatePicker" namespace="BasicFrame.WebControls" tagprefix="BDP" %>
   <div id="divreg" runat="server">
   <table id="tbl" runat="server">
   <tr>
   <td>
    <asp:Label ID="lbl2" runat="server"></asp:Label>
   </td>
   </tr>
   <tr>
   <td> Visa Number:</td>
   <td><asp:TextBox ID="txtUser" Width="160px" runat="server"/></td>
   <td> Country Name:</td>
   <td><asp:DropDownList ID="dropCountry" Width="165px" runat="server">         </asp:DropDownList></td>
   </tr>
   <tr>
   <td> Type of Visa:</td>
   <td><asp:DropDownList ID="dropVisa" Width="165px" runat="server"></asp:DropDownList> </td>
   <td> Type of Entry:</td>
   <td><asp:DropDownList ID="dropEntry" Width="165px" runat="server"></asp:DropDownList></td>
   </tr>
   <tr>
    <td> Expiry Date</td>
   <td><BDP:BasicDatePicker ID="basicdate" runat="server"></BDP:BasicDatePicker></td>
   <td>
   <asp:Button ID="btnRemove" Text="Remove" runat="server" OnClick="btnRemove_Click" />
   </td>
   </tr>
   </table>
   </div>

.ascx.cs

protected void Page_Load(object sender, EventArgs e)
{
    txtUser.Text = Request.Form[txtUser.UniqueID];
    dropCountry.SelectedValue = Request.Form[dropCountry.UniqueID];
    dropVisa.SelectedValue = Request.Form[dropVisa.UniqueID];
    dropEntry.SelectedValue = Request.Form[dropEntry.UniqueID];
    //Here I'm getting null value  
    basicdate.SelectedValue = Request.Form[basicdate.UniqueID];
}

public string TextVisaNumber
{
    get { return txtUser.Text; }
    set { txtUser.Text = value; }
}

public DateTime ExpiryDate
{
    get
    {
        return basicdate.SelectedDate;
    }
    set
    {
        basicdate.SelectedDate = value;
    }
}

在下图中,当我给文本框、下拉列表和日期选择器时,我点击添加按钮控件添加文本框,下拉值存在但日期选择器值消失

有什么想法吗?提前致谢

【问题讨论】:

    标签: c# asp.net user-controls viewstate


    【解决方案1】:

    所以,这段代码会和你的有点不同,但我知道它有效。我已经在这里工作了好几个星期了。我有一个预渲染、创建视图状态和加载视图状态。每当我的一个值发生变化时,我都会将其保存到我设置的私有属性中。

        //Global ViewState Variables
        private DataTable networksInfo;
        private string HHmm;
        private string Window;
        private string ZoomFactorTop;
        private string ZoomFactorBottom;
        protected Boolean autoRefresh; 
    
        /// <summary>
        /// This page prerender allows me to save viewstate objects before anything bad
        /// happens. It's going to save any data that needs to persist across postbacks,
        /// since the page refreshes with an autorefresh. Whenever updated, the ViewState
        /// will also need to be updated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Page_PreRender(object sender, EventArgs e)
        {
            // Save the ViewStateObjects before the page is rendered.
            ViewState.Add("networksListVS", networksInfo);
            ViewState.Add("HHmmVS", HHmm);
            ViewState.Add("WindowVS", Window);
            ViewState.Add("ZoomFactorTopVS", ZoomFactorTop);
            ViewState.Add("ZoomFactorBottomVS", ZoomFactorBottom);
            ViewState.Add("AutoRefresh", autoRefresh);
        }
    
        protected void Create_ViewState(DateTime now)
        {
            //Populate Dropdown handles the initial value for networksInfo, but none of the others are
    
            //Set ViewState Vars' initial values
            if (ViewState["HHmmVS"] == null)
            {
                int HH = now.Hour;
                int mm = now.Minute;
    
                Change_Time(HH, mm);
    
            }
            if (ViewState["WindowVS"] == null)
            {
                //The default time window to view is 6 hours
                Window = "6";
            }
            if (ViewState["ZoomFactorTopVS"] == null)
            {
                //The default zoom factor is Window + 0
                ZoomFactorTop = "0";
            }
            if (ViewState["ZoomFactorBottomVS"] == null)
            {
                //The default zoom factor is Window + 0
                ZoomFactorBottom = "0";
            }
            if(ViewState["AutoRefresh"] == null)
            {
                autoRefresh = true;
            }
        }
    
        protected void Load_ViewState()
        {
            //Before updating the charts, we know that this is a postback and that the viewstate shouldn't
            //be null, but check anyways, just to be sure
            if (ViewState["networksListVS"] != null)
            {
                networksInfo = (DataTable)ViewState["networksListVS"];
            }
            if (ViewState["HHmmVS"] != null)
            {
                HHmm = (String)ViewState["HHmmVS"];
            }
            if (ViewState["WindowVS"] != null)
            {
                Window = (String)ViewState["WindowVS"];
            }
            if (ViewState["ZoomFactorTopVS"] != null)
            {
                ZoomFactorTop = (String)ViewState["ZoomFactorTopVS"];
            }
            if (ViewState["ZoomFactorBottomVS"] != null)
            {
                ZoomFactorBottom = (String)ViewState["ZoomFactorBottomVS"];
            }
            if (ViewState["AutoRefresh"] != null)
            {
                autoRefresh = (Boolean)ViewState["AutoRefresh"];
            }
        }
    

    事实上,我的一个变量是一个日历对象。我让它工作的方式是,如果用户选择较旧的时间,他们不希望页面刷新并且自动刷新关闭。

    如果这不是您关心的问题,最简单的做法与您正在做的事情类似,即只保存表示日期时间对象的状态。

    现在,根据我阅读的内容,您需要一个预渲染(尽管这可以在页面加载中完成)、一个创建视图状态(也可以在那里完成)和一个加载视图状态。我看到的是,您可能想要外部变量,而不是获取/设置之类的东西来保存这些值,因为当我保存我的视图状态时,它看起来更像这样:

                    ZoomFactorTop = "0";
                    ZoomFactorBottom = "0";
    
                    //Save the changes just made to the objects the ViewState needs access to
                    SaveViewState();
    

    希望对一些人有所帮助!

    【讨论】:

      【解决方案2】:

      您可以将值存储在隐藏控件中,并在回发时将值恢复到适当的控件中,如果涉及 jquery,我猜是这样,它经常忘记回发时的值,无论是否启用视图状态等。

      查看at this blog post 以使用隐藏字段值将数据选择器值设置为就绪。

      这是上述博文中的代码:

      <table>
      <tr>
          <td>
              <asp:CheckBox ID="chkEnableMonthlyNotifications" runat ="server" CssClass="cell-Text" Text="Enable monthly notifications." />
              <br/>
          </td>
      </tr>
      <tr>
          <td>
              <label for="txtMonthStartDate">Specify start date for monthly notification</label>
              <br />
              <br />
              <asp:TextBox ID="txtMonthStartDate" runat="server" Enabled="true"></asp:TextBox>
              <asp:HiddenField ID="hdnMonthStartDate" runat="server" />
          </td>
      </tr>
      <tr>
          <td>
              <label for="txtMonthEndDate">Specify end date for monthly notification, or leave blank if no end date.</label>
              <br />
              <br />
              <asp:TextBox ID="txtMonthEndDate" runat="server" Enabled="true" > </asp:TextBox>
              <asp:HiddenField ID="hdnMonthEndDate" runat="server" />
          </td>
      </tr>
      </table>
      

      jQuery 使用备用字段初始化 Datepicker

      $(document).ready(function ()
      {
         $("[id$=_txtMonthStartDate]").datepicker({ showOn: 'button', buttonImageOnly: true, buttonImage: '/icon_cal.png', altField: '[id$=_hdnMonthStartDate]' });
         $("[id$=_txtMonthEndDate]").datepicker({ showOn: 'button', buttonImageOnly: true, buttonImage: '/icon_cal.png', altField: '[id$=_hdnMonthEndDate]' });
         $("[id$=_txtQuarterStartDate]").datepicker({ showOn: 'button', buttonImageOnly: true, buttonImage: '/icon_cal.png', altField: '[id$=_hdnQuarterStartDate]' });
         $("[id$=_txtQuarterEndDate]").datepicker({ showOn: 'button', buttonImageOnly: true, buttonImage: '/icon_cal.png', altField: '[id$=_hdnQuarterEndDate]' });
         $("[id$=_txtHalfYearStartDate]").datepicker({ showOn: 'button', buttonImageOnly: true, buttonImage: '/icon_cal.png', altField: '[id$=_hdnHalfYearStartDate]' });
         $("[id$=_txtHalfYearEndDate]").datepicker({ showOn: 'button', buttonImageOnly: true, buttonImage: '/icon_cal.png', altField: '[id$=_hdnHalfYearEndDate]' });
         $("[id$=_txtYearStartDate]").datepicker({ showOn: 'button', buttonImageOnly: true, buttonImage: '/icon_cal.png', altField: '[id$=_hdnYearStartDate]' });
         $("[id$=_txtYearEndDate]").datepicker({ showOn: 'button', buttonImageOnly: true, buttonImage: '/icon_cal.png', altField: '[id$=_hdnYearEndDate]' });
      }
      

      在 document.ready 上再次设置 Datepicker 日期的 jQuery 代码

      $(document).ready(function ()
      {
        //Initializing the datepicker
      
        $("[id$=_txtMonthStartDate]").datepicker({ showOn: 'button', buttonImageOnly: true, buttonImage: '/icon_cal.png', altField: '[id$=_hdnMonthStartDate]' });
      
        //Code to set the datepicker's date again after post back
        if(!($("[id$=_txtMonthStartDate]").attr("Value") == undefined))
        {
          if($("[id$=_txtMonthStartDate]").attr("Value").length > 0)
          {
              $("[id$=_txtMonthStartDate]").datepicker("setDate",new Date($("[id$=_txtMonthStartDate]").val($("[id$=_txtMonthStartDate]").attr("Value"))));
          }
        }
      }
      

      【讨论】:

      • 是的,我以前也这样做过。不过,这不是最安全或最佳的做法。一旦我终于让 viewstate 工作起来,它就简单多了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多