为ASP.NET用户控件启用PostBack

时间:2010-04-30 19:12:41

标签: asp.net vb.net user-controls postback

当我点击“查询”按钮时,我的TestID文本框TestIDTxt保留了其值,但两个myDatePicker都是空白而没有任何值。

问题:如何在回发之间保留StartDate.SelectedDate和EndDate.SelectedDate?

解决方案: 多次建议,删除ReadOnly="true"上的DateTxt会在回发中保留文本值。 (谢谢Raj Kaimal!)

然后我在{_ 1}}设置SelectedDate自动设置该用户控件的Page_Load()上的文本值,请参阅下面的代码。

我从未直接使用过ViewState对象。

myDatePicker.ascx.vb(最终)

Date.Parse

myDatePicker.ascx.vb(ORIGINAL)

Imports System.Globalization
Partial Public Class myDate
    Inherits System.Web.UI.UserControl

    Public Property SelectedDate() As Date?
        Get 'Simply return the date'
            Return Me.DateTxt_CalendarExtender.SelectedDate
        End Get
        Set(ByVal value As Date?)
            If value = Nothing Then Exit Property
            Me.DateTxt_CalendarExtender.SelectedDate = value
            Me.DateTxt.Text = Format(value, Me.DateTxt_CalendarExtender.Format)
        End Set
    End Property

    Public Sub Refresh()
        Dim tempDate As Date 'SelectedDate is nullable Date (Date?)'
        Dim parseState As Boolean = False

        parseState = Date.TryParseExact(DateTxt.Text, _
                                        DateTxt_CalendarExtender.Format, _
                                        DateTimeFormatInfo.CurrentInfo, _
                                        DateTimeStyles.None, tempDate)
        If parseState Then 'if successful, set the date'
            Me.DateTxt_CalendarExtender.SelectedDate = tempDate
        End If
    End Sub

    Private Sub Page_Load(ByVal sender As Object, _
                          ByVal e As System.EventArgs) Handles Me.Load
        Me.Refresh()
    End Sub
End Class

myDatePicker.ascx

Partial Public Class myDate
    Inherits System.Web.UI.UserControl

    Public Property SelectedDate() As Date?
        Get
            Dim o As Object = ViewState("SelectedDate")
            If o = Nothing Then
                Return Nothing
            End If
            Return Date.Parse(o)
        End Get
        Set(ByVal value As Date?)
            ViewState("SelectedDate") = value
        End Set
    End Property
End Class

Default.aspx的

<%@ Control Language="vb" CodeBehind="myDatePicker.ascx.vb"
    Inherits="Website.myDate" AutoEventWireup="false" %>

<%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" 
             tagprefix="asp" %>

<asp:TextBox ID="DateTxt" runat="server" ReadOnly="True" />
<asp:Image ID="DateImg" runat="server" ImageUrl="~/Calendar_scheduleHS.png"
              EnableViewState="True" EnableTheming="True" />

<asp:CalendarExtender ID="DateTxt_CalendarExtender" runat="server" Enabled="True"
                      TargetControlID="DateTxt" PopupButtonID="DateImg"
                      DefaultView="Days" Format="ddd MMM dd, yyyy"
                      EnableViewState="True"/>

Default.aspx.vb

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb"
         Inherits="Website._Default" EnableEventValidation="false"
         EnableViewState="true" %>

<%@ Register TagPrefix="my" TagName="DatePicker" Src="~/myDatePicker.ascx" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit"
             TagPrefix="ajax" %>
<%@ Register Assembly="..." Namespace="System.Web.UI.WebControls"
             TagPrefix="asp" %>

<!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">
...
<body>
<form id="form1" runat="server">
<div class="mainbox">
      <div class="query">
          Start Date<br />
          <my:DatePicker ID="StartDate" runat="server" EnableViewState="True" />
          End Date
          <br />
          <my:DatePicker ID="EndDate" runat="server" EnableViewState="True" />
        <br/>
        <asp:TextBox ID="TestIdTxt" runat="server" /><br /> 
        <div class="query_buttons">
            <asp:Button ID="Button1" runat="server" Text="Query" />
        </div>
 </div>
 <asp:GridView ID="GridView1" ... >
 </form>
 </body>
 </html>

8 个答案:

答案 0 :(得分:3)

您的文本框是只读的,因此它不会在视图状态中存储对文本值的任何更改。这是一种安全功能,可防止对只读控件的篡改。

首先,如果删除readonly属性,一切都能正常工作吗?

  

我希望用户控件与回发之前完全相同(外观和值)。

如果是这样,你可以使用css / jquery使文本框字段显示为禁用吗?

答案 1 :(得分:2)

  

我希望用户控件完全正确   在回发之前是什么(在   外观和价值)。

您可以尝试使用ControlState

在你的init处理程序中:

protected override void OnInit(EventArgs e) 
{
    Page.RegisterRequiresControlState(this);
}

在你控制的其他地方:

    protected override object SaveControlState()
    {
        NameValueCollection state = new NameValueCollection();
        state.Add("value", this.DateTxt.Text);
        return state;
    }

    protected override void LoadControlState(object savedState)
    {
        NameValueCollection state = (NameValueCollection)savedState;
        this.DateTxt.Text = state["value"].ToString();
    }

我根据我的一些代码改编了这个,所以你可能需要为你的目的调整一下。 ASP.NET运行时将在页面生命周期中调用这两个方法,以独立于ViewState的方式为您保存和恢复该文本框的值。

答案 2 :(得分:1)

使用只读文本框时,CalendarExtender无法正常工作。有一个相对简单的解决方法,虽然它看起来有点脏,并不是真正的webforms方式。尝试将其放在Page_Load:

DateTxt.Text = Request[DateTxt.UniqueID]

显然,如果你在某些情况下也从ViewState填充文本框,你也需要注意这一点。

答案 3 :(得分:0)

将按钮的onclick事件设置为代码中的事件处理程序:

<asp:Button ID="Button1" runat="server" Text="Query" OnClick="MyButtonClickEventHandler" />

答案 4 :(得分:0)

这是一篇应该提供帮助的文章

http://msdn.microsoft.com/en-us/library/ms972975.aspx

基本上你需要创建一个导致回发的事件

答案 5 :(得分:0)

如果我未解决您的问题,您只需要在myDate类中重载UserControl.DataBind。

查看here以获取更好的文档。

如果使用textfield等内部组件创建组件,则可以执行以下示例。因此,将输入或修改的数据绑定到内部组件,并确保跟踪状态,并在每次回发时保存/加载它。

如果您绘制自己的组件,请确保覆盖DataBinding,因为您必须记录视图状态中的用户输入,但要复杂得多。

简单UserControl的示例: WebUserControl1.ascx.vb:

    Public Class WebUserControl1
    Inherits System.Web.UI.UserControl

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub


    Public Property SelectedText() As String
        Get
            Return TextBox1.Text
        End Get
        Set(ByVal value As String)
            TextBox1.Text = value
        End Set
    End Property

    Public Overrides Sub DataBind()
        MyBase.OnDataBinding(EventArgs.Empty)
        ' Reset the control's state.
        ' Controls.Clear()
        ' Check for HasChildViewState to avoid unnecessary calls to ClearChildViewState.
        If HasChildViewState Then
            ClearChildViewState()
        End If
        ChildControlsCreated = True
        If Not IsTrackingViewState Then
            TrackViewState()
        End If
    End Sub


    Protected Overrides Sub LoadControlState(ByVal savedState As Object)
        SelectedText = savedState


    End Sub

    Protected Overrides Function SaveControlState() As Object
        Return SelectedText

    End Function
End Class

WebUserControl1.ascx:

<%@ Control Language="vb" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.vb" Inherits="WebApplication1.WebUserControl1" %>
PIPPO:
<asp:TextBox ID="TextBox1" runat="server" Width="384px"></asp:TextBox>

Default.aspx的:

<%@ Register src="WebUserControl1.ascx" tagname="WebUserControl1" tagprefix="uc2" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">

    <br />
    -----------------------------------<br />

    <uc2:WebUserControl1 ID="WebUserControl11" runat="server" SelectedText="aaaa" />
    <br />
    -----------------------------------<br />
    <asp:Button ID="Button1" runat="server" Text="Button" />
    <br />
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    <br />

</asp:Content>

Default.aspx.vb

Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        DataBindChildren()
    End Sub

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        Label1.Text = WebUserControl11.SelectedText


    End Sub
End Class

答案 6 :(得分:0)

在用户控件的OnLoad事件中,您可以使用在视图状态中保存的值来填充控件。 (如果这个VB是正确的,则不是100%)

Protected Sub Page_Load(ByVal sender As Object, _
                        ByVal e As EventArgs) Handles Me.Load
    Me.DateTxt_CalendarExtender.(property that sets the date) = Me.SelectedDate
    //or Me.DateTxt_CalendarExtender.(property that sets the date picked) = ViewState["SelectedDate"] As Date
End Sub

答案 7 :(得分:-1)

您应该能够在日历中添加这样的内容,以便在选择日期时自动提交您的页面:

OnClientDateSelectionChanged="document.getElementById('form1').submit();"

如果需要,您可以使用特定按钮替换JavaScript提交,或call an asp.net postback event