【问题标题】:User control (ascx) and properties用户控件 (ascx) 和属性
【发布时间】:2009-07-24 19:23:22
【问题描述】:

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

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

不过,我不能说我对此印象深刻,因为用户控件的属性越多,您在 ViewState 中的垃圾就越多。有没有更好的方法来持久化属性?

【问题讨论】:

  • 所有 Web 控件都以相同的方式执行此操作,这就是 ViewState 变得巨大的原因......
  • 我最后不得不求助于这个。它的工作原理令人非常沮丧,但它确实完成了工作..现在还不错.. :)

标签: asp.net properties user-controls viewstate


【解决方案1】:

这取决于。如果您需要将属性值保留在回发之后,那么您将不得不使用 ViewState 或 Session。由于这些控件是在每次回发时重新创建的,否则您无法真正保持该状态。

【讨论】:

  • 是的,属性值需要通过回发保持。我在用户控件中有一个按钮,单击时会引发按钮事件(duh),此时我需要检索某些属性值。哦,好吧,我猜我只会让 ViewState 膨胀!
  • "要在回发之后持久化,那么您必须使用 ViewState 或 Session"。对于 ViewState 来说,情况并非如此。 ViewState 仅在回发之间持续存在,而不是超出。
【解决方案2】:

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

您的说法“用户控件的属性越多,您在 ViewState 中的垃圾就越多”虽然不一定正确。当然可以让 ViewState 跟踪控件属性的值,但不将数据存储在 __VIEWSTATE 隐藏表单字段变量中。

听起来很疯狂吧?请参阅 TRULY Understanding ViewState 了解有关 ViewState 工作原理的精彩文章。

这取决于您在控件的生命周期中何时初始化控件的属性。 ViewState 只会在StateBag 之后存储在隐藏的__VIEWSTATE 字段中,以便控件开始跟踪对属性值的更改。这发生在生命周期早期的控件的OnInit 方法中,但是有一些技术可以更早地设置属性值,不会产生__VIEWSTATE 膨胀的成本,并且仍然会给您带来所有好处。

查看链接的文章。它比我更清楚地讨论了所有事情:-)

【讨论】:

    【解决方案3】:

    您的问题正是 ViewState 的用途:跨回发保持控件的属性,因此您的解决方案很好。

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

    另外请记住,如果您使用会话,则必须做一些家务。例如,如果您想在同一个页面上使用您的用户控件两次,您需要确保每个控件都使用唯一的会话变量。

    【讨论】:

      【解决方案4】:

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

      您可能还想查看 ControlState——它是一个单独的“包”,人们无法禁用它,用于诸如 GridView 之类的东西,其中有些东西无法通过视图状态关闭,因为它打破了控制。

      【讨论】:

        【解决方案5】:

        您始终可以覆盖预期的 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];
           }
        }
        

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 那么当你有两个请求并且他们都想在用户控件上使用不同的属性时会发生什么?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-20
          • 1970-01-01
          相关资源
          最近更新 更多