代码之家  ›  专栏  ›  技术社区  ›  Jagd Dai

用户控件(ascx)和属性

  •  21
  • Jagd Dai  · 技术社区  · 15 年前

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

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

    不过,我不能说我对此印象深刻,因为用户控件的属性越多,您在视图状态中的停留就越糟糕。有没有更好的方法来保持属性?

    6 回复  |  直到 12 年前
        1
  •  10
  •   Matthew Groves    15 年前

    视情况而定。如果您需要将属性值保留在回发之后,那么您将不得不使用viewstate或session。因为这些控件是在每个回发邮件上重新创建的,所以您不能真正保持这种状态。

        2
  •  8
  •   dariom    15 年前

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

    但是,您的语句“用户控件的属性越多,在视图状态中停留的垃圾就越多”不一定是正确的。当然可以让控件的属性的viewstate跟踪值,但不能将数据存储在 __VIEWSTATE 隐藏表单域变量。

    听起来很疯狂,对吧?见 TRULY Understanding ViewState 关于ViewState如何工作的精彩文章。

    这取决于在控件的生命周期中何时初始化控件的属性。视图状态将只存储在隐藏的 α维视状态 后场 StateBag 对于控件,开始跟踪对属性值的更改。这发生在 OnInit 方法,用于生命周期早期的控件,但有一些技术可以更早地设置属性值,这不会导致 α维视状态 膨胀,仍然会给你所有的好处。

    请参阅相关文章。它讨论的每一件事都非常清楚,比我所能做的更好。

        3
  •  5
  •   Stefan    15 年前

    您的问题正是ViewState的作用:在回发之间持久化控件的属性,所以您的解决方案很好。

    您可以在会话中保存它,但这确实给服务器带来了负担。根据你拥有的用户数量,这会很快变得非常难看。

    还请记住,如果您使用会话,则必须进行一些内务管理。例如,如果要在同一页上使用用户控件两次,则需要确保每个控件使用唯一的会话变量。

        4
  •  2
  •   Wyatt Barnett    15 年前

    这并不太糟糕——这基本上就是内置控件的工作方式,通常会导致预期的行为。最好的办法是,当您不需要在回发之间持久化这些值时,只选择性地禁用viewstate。

    你可能还想看看ControlState——它是一个独立的“包”,人们不能禁用它,它被用于诸如GridView之类的东西,因为它破坏了控件,有些东西无法通过ViewState关闭。

        5
  •  0
  •   Ian Boyd    12 年前

    你总是可以超越预期 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
  •  -1
  •   Jason    15 年前

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