UserControl文本框不会维护状态

时间:2022-01-17 07:10:21

I have a very simple usercontrol, basically a textbox and a label, whose purpose is to toggle between one another. The control is bound during the page's Page_Load event. On the UserControl's Page_Load event, I call the Toggle() function, which shows or hides the appropriate control and sets its text based on a boolean Editable property and string Text property, respectively.

我有一个非常简单的用户控件,基本上是一个文本框和一个标签,其目的是在彼此之间切换。控件在页面的Page_Load事件期间被绑定。在UserControl的Page_Load事件中,我调用Toggle()函数,该函数显示或隐藏适当的控件,并分别根据布尔可编辑属性和字符串Text属性设置其文本。

Here's my Toggle() method (remember Editable and Text are public properties):

这是我的Toggle()方法(记住Editable和Text是公共属性):

Public Sub Toggle()
    If Editable Then
        txtText.Visible = True
        lblText.Visible = False
        txtText.Text = Text
        txtText.CssClass = TextboxCSSClass
    Else
        txtText.Visible = False
        lblText.Visible = True
        lblText.Text = Text
        lblText.CssClass = LabelCSSClass
    End If
End Sub

My problem is also simple: when a button on the page calls the control's Toggle() method, the toggling works fine, but the text disappears! I've tried this with a normal unbound textbox next to it, and the textbox maintains its text value just fine. Is there something I'm missing?

我的问题也很简单:当页面上的按钮调用控件的Toggle()方法时,切换工作正常,但文本消失了!我试过它旁边有一个普通的未绑定文本框,文本框保持其文本值就好了。有什么我想念的吗?

Thanks for your help in advance.

感谢您的帮助。

3 个解决方案

#1


When you set the visible property of a control to False, it will not be rendered in Html thus it can't carry state between pages. Instead consider using MultiView control

当您将控件的visible属性设置为False时,它将不会在Html中呈现,因此它不能在页面之间传送状态。而是考虑使用MultiView控件

#2


I figured it out! I apologize for being dumb. Here's what I was doing wrong: My Get/Set for the Text Property was being stored in a private member. This means that when updates were made to the text, it didn't know, since it wasn't connected to the textbox. Instead, I did the following:

我想到了!我为愚蠢而道歉。这就是我做错了:Text Property的My Get / Set存储在私有成员中。这意味着当对文本进行更新时,它不知道,因为它没有连接到文本框。相反,我做了以下事情:

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

and in my Page_Load event:

在我的Page_Load事件中:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not IsPostBack Then
        lblText.Text = Text
        Toggle()
    End If
End Sub

and now it works fine! Thanks to those that put me down the right path! :)

现在它工作正常!感谢那些让我走上正确道路的人! :)

#3


Update: More info regarding the comments.

更新:有关评论的更多信息。

If you have the viewstate disabled, and you set the text for textboxes, the text is the one in the input control. This can affect you in the uncommon scenario when you are trying to know if a given textbox's value changed.

如果禁用了视图状态,并设置了文本框的文本,则文本是输入控件中的文本。当您尝试了解给定文本框的值是否发生更改时,这会在不常见的情况下影响您。

The above is different for a label, since it isn't an input control. With the viewstate disabled, if you don't set the text on every request, it will show the initial value (try it out). The viewstate is what automatically allows to keep the information accross postbacks for the controls.

以上对于标签是不同的,因为它不是输入控件。禁用视图状态后,如果未在每个请求上设置文本,它将显示初始值(尝试输出)。视图状态是自动允许保持控件的回发信息的内容。

Just as it happens with the label, it happens with your user control. If you change the setter so it sets both controls texts directly, it will keep the value in the inner controls if you are using the viewstate. If you turn it off, it would behave different for the label than for the textbox.

就像标签一样,它发生在用户控件上。如果更改setter使其直接设置两个控件文本,如果使用viewstate,它将保留内部控件中的值。如果将其关闭,则标签的行为与文本框的行为不同。

Also note, that turning off the viewstate, would also affect your Visible configuration. I turn the viewstate off a lot, but you might have an scenario where you really want to keep the controls information accross postbacks. When turning off the viewstate, you need to make sure to always configure the controls, not only when !IsPostBack.

另请注意,关闭视图状态也会影响Visible配置。我关闭了视图状态,但是你可能有一个场景,你真的希望保持控制信息在回发中。关闭视图状态时,您需要确保始终配置控件,而不仅仅是在!IsPostBack时。

Note that if you keep track of what is supposed to be Visible and the text in your code, then you could turn off the inner control's viewstate (assuming you are not assigning any other property to them).

请注意,如果您跟踪应该是Visible的内容以及代码中的文本,那么您可以关闭内部控件的viewstate(假设您没有为它们分配任何其他属性)。


Initial answer:

You are assigning the current value of the Text property to the label/textbox. If you didn't set the value in the current request, then it has its default value, thus you are getting the empty text.

您正在将Text属性的当前值分配给标签/文本框。如果您未在当前请求中设置该值,则它具有其默认值,因此您将获得空文本。

You can save the value in the viewstate as (c# syntax):

您可以将视图状态中的值保存为(c#语法):

public string Text
{
   get
   {
      return (string) ViewState["MyText"];
   }
   set
   {
      ViewState["MyText"] = value;
   }
}

Ps. this isn't the only way to do it. If the toggle didn't set the text, but you did it on the setter to both controls, then they would keep the values (as long as you assign the Text property of the user control after viewstate is being tracked, like in page Load).

PS。这不是唯一的方法。如果切换没有设置文本,但你在两个控件的setter上都做了,那么他们会保留这些值(只要在跟踪viewstate之后分配用户控件的Text属性,就像在页面加载一样)。

#1


When you set the visible property of a control to False, it will not be rendered in Html thus it can't carry state between pages. Instead consider using MultiView control

当您将控件的visible属性设置为False时,它将不会在Html中呈现,因此它不能在页面之间传送状态。而是考虑使用MultiView控件

#2


I figured it out! I apologize for being dumb. Here's what I was doing wrong: My Get/Set for the Text Property was being stored in a private member. This means that when updates were made to the text, it didn't know, since it wasn't connected to the textbox. Instead, I did the following:

我想到了!我为愚蠢而道歉。这就是我做错了:Text Property的My Get / Set存储在私有成员中。这意味着当对文本进行更新时,它不知道,因为它没有连接到文本框。相反,我做了以下事情:

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

and in my Page_Load event:

在我的Page_Load事件中:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not IsPostBack Then
        lblText.Text = Text
        Toggle()
    End If
End Sub

and now it works fine! Thanks to those that put me down the right path! :)

现在它工作正常!感谢那些让我走上正确道路的人! :)

#3


Update: More info regarding the comments.

更新:有关评论的更多信息。

If you have the viewstate disabled, and you set the text for textboxes, the text is the one in the input control. This can affect you in the uncommon scenario when you are trying to know if a given textbox's value changed.

如果禁用了视图状态,并设置了文本框的文本,则文本是输入控件中的文本。当您尝试了解给定文本框的值是否发生更改时,这会在不常见的情况下影响您。

The above is different for a label, since it isn't an input control. With the viewstate disabled, if you don't set the text on every request, it will show the initial value (try it out). The viewstate is what automatically allows to keep the information accross postbacks for the controls.

以上对于标签是不同的,因为它不是输入控件。禁用视图状态后,如果未在每个请求上设置文本,它将显示初始值(尝试输出)。视图状态是自动允许保持控件的回发信息的内容。

Just as it happens with the label, it happens with your user control. If you change the setter so it sets both controls texts directly, it will keep the value in the inner controls if you are using the viewstate. If you turn it off, it would behave different for the label than for the textbox.

就像标签一样,它发生在用户控件上。如果更改setter使其直接设置两个控件文本,如果使用viewstate,它将保留内部控件中的值。如果将其关闭,则标签的行为与文本框的行为不同。

Also note, that turning off the viewstate, would also affect your Visible configuration. I turn the viewstate off a lot, but you might have an scenario where you really want to keep the controls information accross postbacks. When turning off the viewstate, you need to make sure to always configure the controls, not only when !IsPostBack.

另请注意,关闭视图状态也会影响Visible配置。我关闭了视图状态,但是你可能有一个场景,你真的希望保持控制信息在回发中。关闭视图状态时,您需要确保始终配置控件,而不仅仅是在!IsPostBack时。

Note that if you keep track of what is supposed to be Visible and the text in your code, then you could turn off the inner control's viewstate (assuming you are not assigning any other property to them).

请注意,如果您跟踪应该是Visible的内容以及代码中的文本,那么您可以关闭内部控件的viewstate(假设您没有为它们分配任何其他属性)。


Initial answer:

You are assigning the current value of the Text property to the label/textbox. If you didn't set the value in the current request, then it has its default value, thus you are getting the empty text.

您正在将Text属性的当前值分配给标签/文本框。如果您未在当前请求中设置该值,则它具有其默认值,因此您将获得空文本。

You can save the value in the viewstate as (c# syntax):

您可以将视图状态中的值保存为(c#语法):

public string Text
{
   get
   {
      return (string) ViewState["MyText"];
   }
   set
   {
      ViewState["MyText"] = value;
   }
}

Ps. this isn't the only way to do it. If the toggle didn't set the text, but you did it on the setter to both controls, then they would keep the values (as long as you assign the Text property of the user control after viewstate is being tracked, like in page Load).

PS。这不是唯一的方法。如果切换没有设置文本,但你在两个控件的setter上都做了,那么他们会保留这些值(只要在跟踪viewstate之后分配用户控件的Text属性,就像在页面加载一样)。