用户控件(ascx)和属性

时间:2009-07-24 19:23:23

标签: asp.net properties user-controls viewstate

我发现在用户控件中保留属性值的唯一方法是使用ViewState。

public string Title {
        get { return Convert.ToString(ViewState["Title"]); }
        set { ViewState["Title"] = value; }
    }

我不能说我对此印象非常深刻,因为用户控制的属性越多,你就越容易陷入ViewState。是否有更好的方法来坚持财产?

6 个答案:

答案 0 :(得分:10)

这取决于。如果您需要将属性值保留在post-back之外,那么您将不得不使用ViewState或Session。由于这些控件是在每个帖子上重新创建的,否则你无法真正保持这种状态。

答案 1 :(得分:8)

使用ViewState存储用户控件的属性值完全没有问题。

您的声明“用户控件拥有的属性越多,您将在ViewState中保留的垃圾越多”并不一定如此。当然可以让ViewState跟踪控件属性的值,但不能将数据存储在__VIEWSTATE隐藏表单字段变量中。

听起来很疯狂吗?有关ViewState如何工作的精彩文章,请参阅TRULY Understanding ViewState

这取决于何时在其生命周期中初始化控件的属性。对于控件开始跟踪属性值的更改,View __VIEWSTATE之后,ViewState将仅存储在隐藏的StateBag字段中。在生命周期早期的控件的OnInit方法中会发生这种情况,但是有一些技术可以提前设置属性值,但不会产生__VIEWSTATE膨胀的成本,并且仍会为您提供所有好处。

请参阅链接的文章。它比我更清楚,更好地讨论了一切: - )

答案 2 :(得分:5)

您的问题正是ViewState的用途:要在回发后保留控件的属性,所以您的解决方案就可以了。

您可以将其保存在会话中,但这实际上只会给服务器带来负担。根据您拥有的用户数量,这可能会很快变得非常难看。

另请注意,如果使用会话,则必须进行一些内务处理。例如,如果要在同一页面上使用两次用户控件,则需要确保每个控件都使用唯一的会话变量。

答案 3 :(得分:2)

这不是太糟糕 - 这几乎就是内置控件如何工作,并且通常会导致预期的行为。最好的办法是,当您不需要在回发中保留这些值时,有选择地禁用ViewState。

您也可能想要查看ControlState - 它是一个人们无法禁用的独立“包”,并且用于GridView之类的东西,其中有些东西无法通过viewstate关闭,因为它打破了控制。

答案 4 :(得分:0)

您始终可以覆盖预期的SaveViewState / LoadViewState方法:

public string Title { get; set; }

然后根据需要保存并加载:

protected override object SaveViewState()
{
   // Save State as a cumulative array of objects.
   object baseState = base.SaveViewState();

   object[] allStates = new object[2];
   allStates[1] = _title;
   return allStates;
}

protected override void LoadViewState(object savedState)
{
   if (savedState != null)
   {
      // Load State from the array of objects that was saved during SavedViewState.
      object[] myState = (object[])savedState;
      if (myState[0] != null)
         base.LoadViewState(myState[0]);

      if (myState[1] != null)
         _title = (String)myState[1];
   }
}

答案 5 :(得分:-1)

你试过静态属性吗?另外,请记住http是无状态的,因此您可以在每个page_load

重置标题